Testing Smart Contracts with NCTL
NCTL effectively simulates a live Casper network. The process for sending a Deploy
to an NCTL-based network is therefore similar to doing so on a live network.
Testing Deploys
prior to sending them to a Casper network ensures that they operate as intended. When working in an environment that requires payment for execution, errors and inefficiencies quickly add up. To this end, Casper provides several layers of testing to identify and rectify any errors. After writing your smart contract and testing it using the provided framework, NCTL serves as the next step in the process. While testing is entirely optional, it should be considered a best practice to avoid paying for the execution of faulty code.
Getting Started with NCTL
Prior to testing a Deploy
through NCTL, you should have the following steps accomplished:
-
Tested the Deploy using the Casper testing framework
-
Setup NCTL on your system
NCTL Verification Prior to Testing
Prior to attempting an NCTL test, you must verify that your local NCTL instance started correctly. Run the following command to view your current node status:
nctl-status
You should see five nodes RUNNING
and five STOPPED
. Further, verify that the node and user information propagated within the casper-node/utils/assets directory. Each node and user should have the associated Keys
necessary to interact with the network. Run the following command to view first user details:
nctl-view-user-account user=1
Installing the Smart Contract
This document assumes that you setup your NCTL network using the standard settings in a directory called /casper/.
You will need the following information to use the put-deploy
command:
-
The chain name, in this case
casper-net-1
. This will appear in our example put-deploy as--chain-name "casper-net-1"
-
The secret key of the account sending the
Deploy
. For this example, we are using node-1 as the sender. The secret key file can be found at casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem. In our example put-deploy, this will appear as--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem
. If your Deploy is more complex and requires multiple accounts, NCTL also establishes multiple users for testing. -
The payment amount in motes, which should be sufficient to avoid an 'Out of Gas' error. The payment amount will appear in our example put-deploy as
--payment-amount 2500000000
. NCTL tests are not an accurate representation of potential gas costs on a live network. Please see our note about gas prices. -
The path to your
Deploy
that you wish to send to the NCTL network. This will appear in our example put-deploy as--session-path <PATH>
and will require you to define the path to your specificDeploy
Wasm. -
The node address for a node on your NCTL network. In this example, we are using the node at
http://localhost:11101
. On the Casper Mainnet or Testnet, nodes will use port7777
. This will appear in our example put-deploy as--node-address http://<HOST>:7777
.
The command to send your Deploy
should look similar to the following code snippet:
Use of the $(get_path_to_client)
command assumes that you are operating in an activated NCTL envrionment.
$(get_path_to_client) put-deploy \
--chain-name "casper-net-1" \
--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \
--payment-amount 2500000000 \
--session-path <PATH> \
--node-address http://localhost:11101
The response will return something similar to the following information. Note the deploy_hash
:
{
"id": 4824893960188648146,
"jsonrpc": "2.0",
"result": {
"api_version": "1.0.0",
"deploy_hash": "8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13"
}
}
Verifying Deploy Execution
The previous command sent the Deploy
to the NCTL network, but we recommend verifying deploy execution before continuing. The deploy_hash
received in the response allows you to query the Deploy
's status.
To query the Deploy
's status, you will pass both the deploy_hash
and the same node-address
from above using the following command. This will return either an error message in the event of failure or the Deploy
details if it succeeds.
$(get_path_to_client) get-deploy 8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13 -n http://localhost:11101
Interacting with the Installed Contract
Once your NCTL network executes your Deploy
, you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the ContractHash
itself. This hash identifies the contract and allows you to target the included entry points. As we used the pre-established node-1 account to send the Deploy
, we can retrieve the ContractHash
from the node-1 account information. To do so, we will use the following command with a node address and the PublicKey
of the node in question.
$(get_path_to_client) get-account-info \
--node-address http://localhost:11101 \
--public-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/public_key.pem
This command will return information pertaining to the account, including the NamedKeys
. The ContractHash
of the contract to be tested will appear here. The process of calling the contract is similar to that of installing it, as they are both accomplished through sending a Deploy
. In this instance, you will need the following information:
-
The node address, entered in this instance using
--node-address http://localhost:11101
-
The chain name, entered in this instance using
--chain-name "casper-net-1"
-
The payment amount for this
Deploy
in motes, which may need to be adjusted depending on cost and network chainspec. In this instance, we will use--payment-amount 500000000
-
The session path, defining the location of the Wasm bearing file for the
Deploy
. It appears in our example as--session-path <PATH>
but you must define the path to your specific file. -
Any session arguments specific to the contract that you are testing. Multiple instances of
--session-arg
may be used as necessary to provide values to the contract, including theContractHash
you acquired above. In the example below, you will see a demonstration of theContractHash
as a session argument as--session-arg "contract_key:key='hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a'"
$(get_path_to_client) put-deploy \
--node-address http://localhost:11101 \
--chain-name "casper-net-1" \
--payment-amount 500000000 \
--session-path <PATH> \
--session-arg "contract_key:key='hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a'"
Verifying Correct Contract Behavior
After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in global state. Depending on how your contract functions, this can have different meanings and results. If we use our donation contract from the basic smart contract tutorial, the NCTL process would have the following flow:
-
Send a
Deploy
to install the "Donation" smart contract. -
Verify the execution of the
Deploy
. -
Interact with the installed contract using an additional
Deploy
that calls one or several of the entry points. For example, calling thedonate
entry point to donate an amount to the fundraising purse. -
Verify the associated change in global state. Namely, an increase in the balance of the fundraising purse.