NEO Smart Contract Development(1) Mission Impossible
by Li Jianying
Reward mission
Here is a contract as follows
public static object Main(string method, object[] args)
{
if (Runtime.Trigger == TriggerType.Verification)
{
if (method == “0214”)
return true;
}
return false;
}
Its AVM is as follows. As it’s a verification contract, there is no need to deploy it.
55c56b6c766b00527ac46c766b51527ac4616168164e656f2e52756e74696d652e47657454726967676572009c6c766b52527ac46c766b52c3642a00616c766b00c30430323134876c766b53527ac46c766b53c3640e00516c766b54527ac4620f0061006c766b54527ac46203006c766b54c3616c7566
ScriptHash:0x86cf7371f5511257f682cc47be48563a3ff03f51
Address:APBUyZNkemciUQurabSQBnnma7kGGhUPPL
many gas has been transferred to this address on TestNet. The gas belongs to those who can take them.
This mission has been released for 24 hours and known by many blockchain experts, but nobody took it. So it deserves the title of mission impossible.
This article is to talk you out of developing verification contracts and into learning application contract development first.
The learning curve of neo.org documentation is not steep but precipitous.
I did a sampling research, and found that someone has finished the learning of verification contract by following this documentation.
So I decided to climb this steep mountain with full confidence in my learning competence in the hope of teaching you how tolearn verification contract after I learned it well. Now I am back and jumped from the precipice.
These two money is from the reward mission account.
Was the token transfer successful? Partially. I couldn’t be more disheartened when I tried to withdraw the money with NEOGUI.
(https://github.com/NewEconoLab/neo-thinsdk-cs)
I withdrew the money from NEL Thnsdk-cs wallet.
After completing this task, I came to a conclusion:
My advice is to steer clear of verification contract development and learn application contract development first.
The main difficulty is there are many concepts to understand, not enough cooperation from neogui. If you are still not disheartened and insist climbing
The mountain, let’s continue to talk about this.
Password contract
the reward contract is a password contract
public static object Main(string method, object[] args)
{
if (Runtime.Trigger == TriggerType.Verification)
{
if (method == “0214”)
return true;
}
return false;
}
Only when its first parameter is 0214 and when Runtime.Trigger==Verification, it returns true.
For an verification contract, the transaction is only true when it returns true.
It’s easy to think about it. But where do we input this 0214? We need to talk about the whole transaction and
Verificationcontract.
Verification contract and transaction
Verification contract is executed at transaction verification stage. If verification contract doesn’t return true, then this transaction verification fails, it
Can’t be written into the block and can’t be queried.
Verification contract is different from application in essence. Application contract is definitely implemented in the block after it is verified and written into the block.
NEO transaction has input and output. It’s a UTXO model. Transaction input is a list,
each of which is a reference to a UTXO. The output of the transaction is to make a new UTXO.
Transaction input and output is money. Destroy input and make output. If you are still confused about UTXO, please don’t look down. Go back and
Figure out what UTXO is.
A transaction includes the following information:
1. Input list
2. Output list
3. If it’s an application transaction trade, there is also application contract script. And there are others for
Other transactions. All of these constitute unsigned contracts.
Have you found that it has nothing to do with verification contract?
Do you still remember signature? You need your private key to sign the transaction when you send tokens to others?
Actually this is a special case of verification contract.
1. How many witnesses are needed depends on how many input address(payer) in a transaction.
2. To sign a transaction means to add the witnesses of the transaction initiator.
3. NEO is a complete smart contract system. Each witness is two scripts, one is called verification script, the other execution script.
The above three points are puzzling. Don’t rush, there are something more puzzling.
a detailed explanation of signature
1. Each account address of NEO is a script, which is a two-instruction smart contract. The pseudo-code is:
Push publickey
Syscall Checkwitness
The hash value of the script is the user's address, usually the user's address is expressed in the form of strings which is converted from the hash value through base58. The string form is exactly equivalent to the hash value. It can be seen, NEO's address is the hash value of smart contracts. The reverse is also true, the hash value of each smart contract of NEO is an address.
So I can send tokens to a smart contract and withdraw tokens from a smart contract, because my address is actually a smart contract address.
2. The verification script of witnesses is the smart contract this address corresponds to. It can’t be modified and can’t be verified if hash is different.
3. Witness's execution script is a smart contract that is used to provide parameters like a validation script
Let’s go back and have a look what happened when I send some tokens from
My address?
1. There has to be utxo from my address in the input when transferring tokens to others.
2. build transactions.
3. to add witnesses, the verification script is my script.
4. Set the execution script of witness, which is a one-instruction smart contract, its pseudo-code is
Push signdata
5. Send rawdata that contains transaction data and witness data.
6. Verify transactions, execute script push signdata, end. Verification script pushes its own pubkey and checksig. The two parameters of this function is signdata and pubkey. Check it, if it’s successful, transaction is true;
If not successful, the transaction is false.
Is signature much more complex than you imagined?
take the rewards away
After figuring out the relationship between witness and transaction, we can withdraw money from the reward contract.
Let’s build a transfer transaction.
Input n and find utxo from reward contract address as input.
Output1: to your own address
Output2 is optional: get change for the rewards address.
Witness: verification script=rewards contract.
Execution script=parameter
Because the parameter is a string and an array.
Reverse push.
the pseudo-code is
Push0 // add 0
Pack // To build an array with the above 0 means it’s a blank array.
Push bytes(”0214“.as bytes())//push ”0214“
The binary is:00c10430323134
The information has been told you, then you just piece a custom contract together.
NEOGUI has its tools, right? Use F12 to get it out. Go test it. It will be definitely fun. You can understand what is precipitous learning curve is.
And even you’ve done them all right, you can’t take the rewards.
I felt puzzled here for a long time and delved into NEO’s underlaying layers line by line.
There is a restriction. Instruction is only allowed to be pushed in the execution script or the execution of script fails. And
Verification contract fails, the transaction is false.
The pseudo-code of the execution script is:
Push0 //加入0 add 0
Pack // To build an array with the above 0 means a blank array.
Push bytes(”0214“.as bytes())//push ”0214“
the binary:00c10430323134
There is one pack. If it’s beyond allowed range, the transaction must fail.
Then we know that there’s no way to use array type of parameters.
The good thing is the second parameter of the reward contract is useless, you can push whatever you like.
We change the execution script to:
Push0 //add 0
Push bytes(”0214“.as bytes())//push ”0214“
the binary:000430323134
Ok, if you are patient, go play NEOGUI and F12.
not deployed?
If you have read some documents of NEO smart contract. You may find this contract is not deployed.
Smart contracts don’t need to be deployed. You can directly call it. No problem.
Then on what conditions does a smart contract need to be deployed? If this smart contract is to be called by appcall, it has to be deployed on the chain and pay expensive fees. Application
Contract is basically this type. In order to achieve convenient repeated invoke, there is also internal storage. Considering all of these, starting from application contract is much easier than starting
From verification contracts.
Verification contract doesn’t need to be deployed.
What is the other Client?
This is NEL( a Chinese NEO developer community)
This is an example of sdk, prepared for developing light wallets.
C# version
https://github.com/NewEconoLab/neo-thinsdk-cs
typescript version
https://github.com/NewEconoLab/neo-thinsdk-ts
Let’s do a demo. Using this wallet, how to learn verification contracts more smoothly?
NEL WeChat Public account published the method of transfer of tokens with this wallet.
http://www.cnblogs.com/crazylights/p/8338117.htm
initiate C# example
Click the lower thinWallet test, it’s a light wallet test.
Because when we take the rewards, actually we don’t need loadkey. We just open the wallet and take the
Money away without anyone’s signature.
Get utxo from the reward contract address
Right click in the input area, you can add utxo from smart contract.
Copy the reward contract or click loadavm, read from avm.
Then we can see the address of the contract is shown on the below.
let’s select this one with 91.8
Then we can see there is input.
An additional changeback means getting change. We are good guys, so we won’t take them all away.
add output and transfer to yourself
Right click in the output area and add output.
fill out to whom you transfer and token type(gas)
And output automatically adjusts and get the change.
Try sending signature out, if can’t be sent out, it means your witness’s execution script hasn’t been configured.
configuring witness
select witness and right click in the witness area.
Yellow is the verification script and it is the verification contract and can’t be modified.
Red is the configuration of execution script. We use a json to replace this un-visualized configuration.
Rules are added to the string.
Starting with (str) means it’s a string.
Starting with (int) means it’s a biginteger
It’s easy to understand, right?
Click Gencode and execution script is generated. But we know that execution scripts with array is not
Allowed, so we need to modify it.
all right, click OK.
go back, sign and broadcast it.
Done, then we got a transaction id dialog box.
transaction is successful
Wherever you check, you can see the reward has been taken out.
Lastly, there are still money in the rewards. Don’t withdraw them all out at one time. Leave some for those who want to explore.