Did you know that direct invocation transactions are not the only scenario when your contract code will be run?
In it’s general usage you smart contract code can be invoked directly, passing in the input parameters with the types that you specified on initial import. This makes up the majority of calls made to and from contracts that hold thinks like NEP5 tokens or managed asset data in contract storage. However, when a transaction is created to transfer assets like NEO or GAS to or from the contract address, your contract code will also be invoked.
Invoking the contract code when sending or receiving assets for a contract address allows you to provide your contract with the ability to self manage it’s NEO and GAS assets. For example, if your contract allows users to exchange NEO for your NEP5 token, the NEO is deposited into the contract address. This can be done either by directly invoking the contract with the appropriate parameters and attaching the NEO to the transaction; or by executing a asset transfer of NEO to the contract address. In the latter case, you will want the contract code to be able to handle the users deposit of NEO, and processes it in a similar flow to the direct contract invocation.
Additionally, once assets have started to accumulate in the contract address, you are going to want a way to manage those funds directly. So when send transactions are executed on behalf of the contract address, we want to have the ability to approve or disapprove those withdraws on a case by case basis.In order to handle this in your contract code, neo-python provides the method:
boa.blockchain.vm.Neo.Runtime.GetTrigger
GetTrigger is a function that when executed returns whether the contract was invoked as an Application or for Verification. We are also provided with the following constants to aid in our validation:
boa.interop.Neo.TriggerType.Application
boa.interop.Neo.TriggerType.Verification
GetTrigger() == Application
The execution of the smart contract code was invoked directly, and we can expect the input arguments with the types that we specified to be present. In this case we should expect to utilize these input values to determine the resulting state of our contract, and it’s output.
GetTrigger() == Verification
The contract code is being executed to provide a verification of whether or not a transaction involving assets owned by the contract address should be allowed to succeed. In this case we should ultimately have logic that returns a True or False value. Returning True will validate the transaction will allow it to execute successfully. Returning False will reject the transaction, and the transfer will not occur.
Usage Example
In the following example, we will simulate a contract where we have handlers for both Application and Validation triggers. In the Verification trigger handler we will only accept transactions executed by a contract owner, and in the Application trigger we will return a special secret message if the correct input password is provided.
from boa.blockchain.vm.Neo.Runtime import GetTrigger, CheckWitness
from boa.blockchain.vm.Neo.TriggerType import Application, Verification
def Main(password):
trigger = GetTrigger()
if trigger == Verification:
return handleVerification()
elif trigger == Application:
return handleApplication(password)
return False
def handleVerification():
owner = 'AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y'
is_owner = CheckWitness(owner)
if is_owner:
return True
return False
def handleApplication(password):
if password == 'elephant':
return 'banana'
return False
handleVerification
In the case that we are handling a Verification trigger, we will only return True if the address that created the send or receive transaction was the owner that we have hardcoded into our contract code. All other addresses who try to send or withdraw asset to or from this account will have their transactions rejected.
handleApplication
In the cast that we are handling an Application trigger, we will expect a password as an input. If and only if the password provided is elephant, will return the secret message banana. If the correct password is not provided, we will simply return False.
For a more in depth example please refer to the Hasty Ogre Name Service contract code.
If you found this tutorial helpful, please donate at:
NEO/GAS/NEP5 tokens: AR8rRBxgWw5siKsp1dUmfTLy6QQTjcqoqB
ETH/ERC20 tokens: 0x575970777095575fDd12d9cD3B105b41D8DD1344
NANO/XRB: xrb_3rpmim57tqbrb8hhjfzm1x5uk135yhmgqoj7j7wsufpo53e3ad5k93ggy1cd
LTC: M8nZ7FwJXSMAkAfiGmTKjbB7MWpdwsp52d
BTC: 3LcA1ztxFjghexRNWPyGXA59VFU3gF4PTz
BCH: 1LXLiF7SjWGday6gm61hzbYHKbSAMevwXo
Congratulations @z0yo! You received a personal award!
Click here to view your Board
Do not miss the last post from @steemitboard:
Congratulations @z0yo! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Vote for @Steemitboard as a witness to get one more award and increased upvotes!