You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Summary or problem description
We've got two basic mechanisms to verify some permissions or action validity in a contract:
System.Runtime.CheckWitness that checks for scoped witness of the current transaction
CryptoLib.VerifyWithECDsa that can help with signatures of some non-transaction data
The first one is the standard thing that works for any Neo account. The second one only works with some single keys (but can handle secp256k1 curve). Usually the second one is used to check some auxiliary non-Neo-related data like cross-chain headers or state data, while regular Neo accounts provide witness (usually, signature(s)) for Neo transactions.
Creating a transaction for Neo blockchain implies answering to several questions:
Who is paying for it?
What nonce/fees/other technical fields are?
What is the script this transaction will execute?
There are cases where we'd like to free the signer from answering to this questions. The first one can be solved with #2577 (and NeoFS sidechain uses it already), but the other two are somewhat more problematic. They assume some knowledge of Neo transaction structure and (!) NeoVM on the signing side. Of course transaction can be prepared elsewhere, but passing some base64 for wallet to sign is not a good idea in general, signer needs to know what exactly he is signing. This problem intersects strongly with neo-project/proposals#68 (and #2835 duplicate of it), but as mentioned there, it's not that easy in Neo context.
So going from an intent of doing something application-specific to transaction requires some effort. Some contracts try dealing with it by using simple signatures they can check with CryptoLib.VerifyWithECDsa. The data to sign can be anything application wants (like serialized NeoFS container structure) and this structure can be as app-friendly as it can be (only containing app-relevant data), but the approach itself inherently means that only simple single-key accounts could be used, application can't rely on Neo account system in this case and can't have multisignature, contract-based or non-standard accounts using this scheme.
Do you have any solution you want to propose?
Neo account witness in general is three things: account hash (address), invocation script and verification script (which is omitted for contracts), so verification requires executing some code which usually calls System.Crypto.CheckSig or System.Crypto.CheckMultisig. Both operate with the so-called "script container" (usually a transaction), serialized representation of which should be signed. So to be able to verify something we need to run two VM scripts with some specific script container.
We have an ability to run arbitrary read-only scripts in VM since 3.5.0 (System.Runtime.LoadScript from #2756). The only thing left to implement is ability to provide some data to check, overriding ScriptContainer for the execution since both System.Crypto.CheckSig and System.Crypto.CheckMultisig should work. The proposal is to implement this in a System.Crypto.CheckData interop.
It should accept:
data to check (or a hash of it)
address to check this data against
invocation script
verification script (can be null for contracts)
And it should return a simple boolean true/false result (as verification scripts usually do).
This allows to implement dApp-specific trust schemes that are easy to sign on clients that have absolutely no idea what's going on in the blockchain.
Example 1
NeoFS currently only allows single-key accounts and that's exactly because of the limitation described above. Creating a container via NeoFS SDK doesn't require managing transactions since we want to provide an API to manage data and not dealing with sidechain. But internally it's a sidechain transaction that calls NeoFS container contract. Going via System.Crypto.CheckData would allow to have containers owned by multisignature accounts.
Example 2
Consider neo-project/proposals#152 problem. While I understand people there want a very specific compatible solution, let's imagine how the problem of "allowing a spender to spend x amount of funds on behalf of an owner" could be solved with System.Crypto.CheckData (but notice that this is just an example, not a proposal for a fancy transferFrom).
It can be done with just a single transferFrom(spender Hash160, from Hash160, to Hash160, amount Integer, data Any, token String, invocation ByteArray, verification ByteArray) accepting a JWT-like token:
check that the asset is the same as System.Runtime.GetExecutingScriptHash
check that from is the same as iss and spender is the same as sub
check that the token is already valid wrt nbf (in blocks, of course) and has not yet expired wrt exp (also in blocks)
check the sequence number of the token in seq is the next one for the issuer to use (that's to prevent replays, random IDs can be used, but counter (while adding some limitations) requires less storage)
check the requested amount against token's amount
and check the token of course, using System.Crypto.CheckData(token, from, invocation, verification)
if all good, transfer the requested amount of assets of course
So we have a scheme that only adds a single method, can work with a signature for a very simple and easy to understand structure and doesn't even require any transactions on the from side.
Neo Version
Neo 3
Where in the software does this update applies to?
Application Engine
The text was updated successfully, but these errors were encountered:
This can also help for NeoFS withdrawals. As we've said numerous times, in absence of #1573 we have a huge problem with GAS withdrawals from NeoFS mainnet contract. It requires confirmation from all of the alphabet IR nodes, so at the moment this implies collecting votes in the contract itself and consequently leads to a hefty GAS penalty for doing so. Instead a check can be signed in the sidechain and transferred to mainnet contract to withdraw with a single transaction.
We can pass invocation/verification scripts (most likely a concatenation of those) into LoadScript now and get a result, but the problem is that Checksig/Checkmultisig calls will check for a signature of script container (transaction) and not some abstract data. Of course we can have arbitrary logic in scripts, but how do we tie this logic to Neo accounts if this logic is not a verification script?
Summary or problem description
We've got two basic mechanisms to verify some permissions or action validity in a contract:
System.Runtime.CheckWitness
that checks for scoped witness of the current transactionCryptoLib.VerifyWithECDsa
that can help with signatures of some non-transaction dataThe first one is the standard thing that works for any Neo account. The second one only works with some single keys (but can handle secp256k1 curve). Usually the second one is used to check some auxiliary non-Neo-related data like cross-chain headers or state data, while regular Neo accounts provide witness (usually, signature(s)) for Neo transactions.
Creating a transaction for Neo blockchain implies answering to several questions:
There are cases where we'd like to free the signer from answering to this questions. The first one can be solved with #2577 (and NeoFS sidechain uses it already), but the other two are somewhat more problematic. They assume some knowledge of Neo transaction structure and (!) NeoVM on the signing side. Of course transaction can be prepared elsewhere, but passing some base64 for wallet to sign is not a good idea in general, signer needs to know what exactly he is signing. This problem intersects strongly with neo-project/proposals#68 (and #2835 duplicate of it), but as mentioned there, it's not that easy in Neo context.
So going from an intent of doing something application-specific to transaction requires some effort. Some contracts try dealing with it by using simple signatures they can check with
CryptoLib.VerifyWithECDsa
. The data to sign can be anything application wants (like serialized NeoFS container structure) and this structure can be as app-friendly as it can be (only containing app-relevant data), but the approach itself inherently means that only simple single-key accounts could be used, application can't rely on Neo account system in this case and can't have multisignature, contract-based or non-standard accounts using this scheme.Do you have any solution you want to propose?
Neo account witness in general is three things: account hash (address), invocation script and verification script (which is omitted for contracts), so verification requires executing some code which usually calls
System.Crypto.CheckSig
orSystem.Crypto.CheckMultisig
. Both operate with the so-called "script container" (usually a transaction), serialized representation of which should be signed. So to be able to verify something we need to run two VM scripts with some specific script container.We have an ability to run arbitrary read-only scripts in VM since 3.5.0 (
System.Runtime.LoadScript
from #2756). The only thing left to implement is ability to provide some data to check, overridingScriptContainer
for the execution since bothSystem.Crypto.CheckSig
andSystem.Crypto.CheckMultisig
should work. The proposal is to implement this in aSystem.Crypto.CheckData
interop.It should accept:
And it should return a simple boolean true/false result (as verification scripts usually do).
This allows to implement dApp-specific trust schemes that are easy to sign on clients that have absolutely no idea what's going on in the blockchain.
Example 1
NeoFS currently only allows single-key accounts and that's exactly because of the limitation described above. Creating a container via NeoFS SDK doesn't require managing transactions since we want to provide an API to manage data and not dealing with sidechain. But internally it's a sidechain transaction that calls NeoFS container contract. Going via
System.Crypto.CheckData
would allow to have containers owned by multisignature accounts.Example 2
Consider neo-project/proposals#152 problem. While I understand people there want a very specific compatible solution, let's imagine how the problem of "allowing a spender to spend x amount of funds on behalf of an owner" could be solved with
System.Crypto.CheckData
(but notice that this is just an example, not a proposal for a fancytransferFrom
).It can be done with just a single
transferFrom(spender Hash160, from Hash160, to Hash160, amount Integer, data Any, token String, invocation ByteArray, verification ByteArray)
accepting a JWT-liketoken
:The implementation will:
spender
witnessStdLib.JsonDeserialize()
the tokenasset
is the same asSystem.Runtime.GetExecutingScriptHash
from
is the same asiss
andspender
is the same assub
nbf
(in blocks, of course) and has not yet expired wrtexp
(also in blocks)seq
is the next one for the issuer to use (that's to prevent replays, random IDs can be used, but counter (while adding some limitations) requires less storage)amount
against token'samount
System.Crypto.CheckData(token, from, invocation, verification)
So we have a scheme that only adds a single method, can work with a signature for a very simple and easy to understand structure and doesn't even require any transactions on the
from
side.Neo Version
Where in the software does this update applies to?
The text was updated successfully, but these errors were encountered: