Greeting - a smart contract property

In our Hello World example, we do one thing and that is initialize the Greeting property:

this.Greeting = "Hello World!";

The actual line initiating the Greeting property is fairly self-explanatory. Let’s take a look at the property getter and setters.

private string Greeting
{
    get
    {
        return this.PersistentState.GetString("Greeting");
    }
    set
    {
        this.PersistentState.SetString("Greeting", value);
    }
}

The PersistentState property belongs to the SmartContract class and facilitates the storage and retrieval of data (in this case a string). Smart contract data is stored as a series of key-value pairs and in this case Greeting is used as the key. The Greeting property is marked as private as there is no need for it to be accessed from anywhere other than inside the smart contract. Unlike methods, C# properties on a smart contract cannot be called even if they are public.

SayHello() - a smart contract method

Finally, let’s look at the simple method Greeting(), which returns the “Hello World!” string.

public string SayHello()
{
    return this.Greeting;
}

As you can see, this method just accesses the Greeting property.

Compiling the Hello World smart contract

A smart contract in C# must be compiled into CIL before it can be deployed. For this, we are going to use the Stratis Smart Contract Tool.

git clone https://github.com/stratisproject/Stratis.SmartContracts.Tools.Sct

Execute the following command: dotnet run validate [PATH_TO_SMART_CONTRACT] -sb. A relative path to `HelloWorld.cs in your Stratis Full Node repository should work fine.

To see more information on the options available for the sct validate command, use the following command: dotnet run validate --help

To see the general help on the sct, use the following command: dotnet run --help

The output from executing the Smart Contract validation will look like the below:

Smart Contract Validator

Compiling ..\HelloWorld.cs...
Compilation OK

Building ModuleDefinition
ModuleDefinition built successfully

Validating file ..\HelloWorld.cs...

====== Smart Contract Validation results for file ..\HelloWorld.cs ======
Compilation Result
Compilation OK: True

Format Validation Result
Format Valid: True

Determinism Validation Result
Determinism Valid: True



Hash
e6cff849009d3bd01d2db606a10bb5a792ce4a0a995f33a2621bcc1c06d8a766

ByteCode
4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C010200D45806930000000000000000E00022200B0130000006000000020000000000003A250000002000000040000000000010002000000002000004000000000000000400000000000000006000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000E82400004F000000000000000000000000000000000000000000000000000000004000000C000000CC2400001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E7465787400000040050000002000000006000000020000000000000000000000000000200000602E72656C6F6300000C0000000040000000020000000800000000000000000000000000004000004200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C250000000000004800000002000500942000003804000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004602280500000A72010000706F0600000A2A4A02280500000A7201000070036F0700000A2A4E0203280800000A02721300007028020000062A1E0228010000062A00000042534A4201000100000000000C00000076342E302E33303331390000000005006C00000080010000237E0000EC0100009801000023537472696E677300000000840300003000000023555300B4030000100000002347554944000000C40300007400000023426C6F6200000000000000020000014715A0010900000000FA01330016000001000000080000000200000004000000020000000800000004000000010000000100000002000000010000000200000000000E0101000000000006008C0042010600BC004201060078002F010F00620100000A00AC0071010A00880171010A002C0071010A0053007101000000000100000000000100010001001000210000001900010001005020000000008108F4002F00010062200000000081080101330001007520000000008618290120000200892000000000860020012F00030000000100DA00000001004000090029010100110029010600190029010A002900290106003100640010004100E00015004100EA001A003100290120002E000B003C002E00130045002E001B006400430023006D00020001000000050138000200010003000100020003000480000000000000000000000000000000008801000004000000000000000000000026000A000000000001000200010000000000000000007101000000000000003C4D6F64756C653E0053797374656D2E507269766174652E436F72654C69620048656C6C6F576F726C640049536D617274436F6E7472616374537461746500736D617274436F6E74726163745374617465004950657273697374656E745374617465006765745F50657273697374656E7453746174650044656275676761626C6541747472696275746500436F6D70696C6174696F6E52656C61786174696F6E73417474726962757465004465706C6F794174747269627574650052756E74696D65436F6D7061746962696C6974794174747269627574650076616C756500476574537472696E6700536574537472696E67006765745F4772656574696E67007365745F4772656574696E6700536D617274436F6E74726163742E646C6C0053617948656C6C6F002E63746F720053797374656D2E446961676E6F73746963730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300446562756767696E674D6F64657300537472617469732E536D617274436F6E74726163747300536D617274436F6E747261637400000000114700720065006500740069006E0067000019480065006C006C006F00200057006F0072006C006400210000000000434394DDB1A99046A0225689C4922D470004200101080320000105200101111104200012210420010E0E052002010E0E05200101121D087CEC85D7BEA7798E0320000E042001010E0328000E0801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F77730108010002000000000004010000000000000000000000000000000000100000000000000000000000000000001025000000000000000000002A2500000020000000000000000000000000000000000000000000001C250000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF2500200010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C0000003C3500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
======

Note

If you are building the Stratis Smart Contract Tool from source and have previously cloned the repository, please ensure that before you compile any smart contracts, you sync the repository to the latest version of the source code and rebuild the tool.

Interact with the Wallet

Begin by making sure that you have the local development network running.

docker container ls

You should now be in possession of 100,000,000 CRS-TEST tokens within your wallet! You can confirm this by interacting with the Balance endpoint, but first, let’s confirm the name of the wallet.

curl -X GET "http://localhost:38223/api/Wallet/list-wallets" -H "accept: application/json"

You should get a response like the below.

{"walletNames":["cirrusdev"],"watchOnlyWallets":[]}

The balance can now be queried by listing the addresses related to the previously discovered wallet.

curl -X GET "http://localhost:38223/api/Wallet/addresses?WalletName=cirrusdev&AccountName=account%200" -H "accept: application/json" | jq '.'

Note

jq has been utilised to prettify the JSON repsonse.

The above GET will return a list of addresses, we need to find the address that has reiceved the pre-mine amount, this will be evident by the amountConfirmed value.

{
        "address": "P9zz49VdoPrirKhU2DBytwVTdCupcR4wYh",
        "isUsed": false,
        "isChange": false,
        "amountConfirmed": 0,
        "amountUnconfirmed": 0
}

Deploying the HelloWorld contract

Now we have interacted with the wallet, we have an address that we know has a balance to fund the associated costs with deploying the contract in question.

The contract can be deployed by utilising the SmartContractWallet/Create endpoint.

curl -X POST "http://localhost:38223/api/SmartContractWallet/create" -H "accept: application/json" -H "Content-Type: application/json-patch+json" -d "{ \"walletName\": \"cirrusdev\", \"amount\": \"0\", \"feeAmount\": \"0.001\", \"password\": \"stratis\", \"contractCode\": \"4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C010200D45806930000000000000000E00022200B0130000006000000020000000000003A250000002000000040000000000010002000000002000004000000000000000400000000000000006000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000E82400004F000000000000000000000000000000000000000000000000000000004000000C000000CC2400001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E7465787400000040050000002000000006000000020000000000000000000000000000200000602E72656C6F6300000C0000000040000000020000000800000000000000000000000000004000004200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C250000000000004800000002000500942000003804000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004602280500000A72010000706F0600000A2A4A02280500000A7201000070036F0700000A2A4E0203280800000A02721300007028020000062A1E0228010000062A00000042534A4201000100000000000C00000076342E302E33303331390000000005006C00000080010000237E0000EC0100009801000023537472696E677300000000840300003000000023555300B4030000100000002347554944000000C40300007400000023426C6F6200000000000000020000014715A0010900000000FA01330016000001000000080000000200000004000000020000000800000004000000010000000100000002000000010000000200000000000E0101000000000006008C0042010600BC004201060078002F010F00620100000A00AC0071010A00880171010A002C0071010A0053007101000000000100000000000100010001001000210000001900010001005020000000008108F4002F00010062200000000081080101330001007520000000008618290120000200892000000000860020012F00030000000100DA00000001004000090029010100110029010600190029010A002900290106003100640010004100E00015004100EA001A003100290120002E000B003C002E00130045002E001B006400430023006D00020001000000050138000200010003000100020003000480000000000000000000000000000000008801000004000000000000000000000026000A000000000001000200010000000000000000007101000000000000003C4D6F64756C653E0053797374656D2E507269766174652E436F72654C69620048656C6C6F576F726C640049536D617274436F6E7472616374537461746500736D617274436F6E74726163745374617465004950657273697374656E745374617465006765745F50657273697374656E7453746174650044656275676761626C6541747472696275746500436F6D70696C6174696F6E52656C61786174696F6E73417474726962757465004465706C6F794174747269627574650052756E74696D65436F6D7061746962696C6974794174747269627574650076616C756500476574537472696E6700536574537472696E67006765745F4772656574696E67007365745F4772656574696E6700536D617274436F6E74726163742E646C6C0053617948656C6C6F002E63746F720053797374656D2E446961676E6F73746963730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300446562756767696E674D6F64657300537472617469732E536D617274436F6E74726163747300536D617274436F6E747261637400000000114700720065006500740069006E0067000019480065006C006C006F00200057006F0072006C006400210000000000434394DDB1A99046A0225689C4922D470004200101080320000105200101111104200012210420010E0E052002010E0E05200101121D087CEC85D7BEA7798E0320000E042001010E0328000E0801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F77730108010002000000000004010000000000000000000000000000000000100000000000000000000000000000001025000000000000000000002A2500000020000000000000000000000000000000000000000000001C250000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF2500200010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C0000003C3500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\", \"gasPrice\": 100, \"gasLimit\": 100000, \"sender\": \"P9zz49VdoPrirKhU2DBytwVTdCupcR4wYh\"}"

A prettified instance of the data passed can be seen below.

{
        "walletName": "cirrusdev",
        "amount": "0",
        "feeAmount": "0.001",
        "password": "password",
        "contractCode":"4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C010200D45806930000000000000000E00022200B0130000006000000020000000000003A250000002000000040000000000010002000000002000004000000000000000400000000000000006000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000E82400004F000000000000000000000000000000000000000000000000000000004000000C000000CC2400001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E7465787400000040050000002000000006000000020000000000000000000000000000200000602E72656C6F6300000C0000000040000000020000000800000000000000000000000000004000004200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C250000000000004800000002000500942000003804000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004602280500000A72010000706F0600000A2A4A02280500000A7201000070036F0700000A2A4E0203280800000A02721300007028020000062A1E0228010000062A00000042534A4201000100000000000C00000076342E302E33303331390000000005006C00000080010000237E0000EC0100009801000023537472696E677300000000840300003000000023555300B4030000100000002347554944000000C40300007400000023426C6F6200000000000000020000014715A0010900000000FA01330016000001000000080000000200000004000000020000000800000004000000010000000100000002000000010000000200000000000E0101000000000006008C0042010600BC004201060078002F010F00620100000A00AC0071010A00880171010A002C0071010A0053007101000000000100000000000100010001001000210000001900010001005020000000008108F4002F00010062200000000081080101330001007520000000008618290120000200892000000000860020012F00030000000100DA00000001004000090029010100110029010600190029010A002900290106003100640010004100E00015004100EA001A003100290120002E000B003C002E00130045002E001B006400430023006D00020001000000050138000200010003000100020003000480000000000000000000000000000000008801000004000000000000000000000026000A000000000001000200010000000000000000007101000000000000003C4D6F64756C653E0053797374656D2E507269766174652E436F72654C69620048656C6C6F576F726C640049536D617274436F6E7472616374537461746500736D617274436F6E74726163745374617465004950657273697374656E745374617465006765745F50657273697374656E7453746174650044656275676761626C6541747472696275746500436F6D70696C6174696F6E52656C61786174696F6E73417474726962757465004465706C6F794174747269627574650052756E74696D65436F6D7061746962696C6974794174747269627574650076616C756500476574537472696E6700536574537472696E67006765745F4772656574696E67007365745F4772656574696E6700536D617274436F6E74726163742E646C6C0053617948656C6C6F002E63746F720053797374656D2E446961676E6F73746963730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300446562756767696E674D6F64657300537472617469732E536D617274436F6E74726163747300536D617274436F6E747261637400000000114700720065006500740069006E0067000019480065006C006C006F00200057006F0072006C006400210000000000434394DDB1A99046A0225689C4922D470004200101080320000105200101111104200012210420010E0E052002010E0E05200101121D087CEC85D7BEA7798E0320000E042001010E0328000E0801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F77730108010002000000000004010000000000000000000000000000000000100000000000000000000000000000001025000000000000000000002A2500000020000000000000000000000000000000000000000000001C250000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF2500200010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C0000003C3500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "gasPrice": 100,
        "gasLimit": 100000,
        "sender": "P9zz49VdoPrirKhU2DBytwVTdCupcR4wYh"
}

Note

The password for the wallet password.

The response recieved will be a Transaction ID.

"8241686211eb182a0a153f9b2e9440a703fd848eb92c26e18be403090da05f7b"

This Transaction ID can be used to confirm that the contract deployment has been accepted and also provide information about the deployment. This is done by interacting with the /SmartContracts/receipt endpoint.

curl -X GET "http://localhost:38223/api/SmartContracts/receipt?txHash=8241686211eb182a0a153f9b2e9440a703fd848eb92c26e18be403090da05f7b" -H "accept: application/json"

The response of this will tell you several things, the amount of GAS that was consumed, the status of the deployment and importantly, the address of the deployed contract.

{
        "transactionHash": "8241686211eb182a0a153f9b2e9440a703fd848eb92c26e18be403090da05f7b",
        "blockHash": "bd033d197b6f6f7b7962ef2a42c29e2be6a7de9d278a0aa4d61e335bcb4ddb61",
        "postState": "1bed6aa13b7eb3a8714a2c81bde8c7442afbb8695a9cb3be6f59f216bbc90617",
        "gasUsed": 12428,
        "from": "P9zz49VdoPrirKhU2DBytwVTdCupcR4wYh",
        "to": null,
        "newContractAddress": "PWyA6fYiGFbJxaLqpPq3aSyGkHw9QNv9kY",
        "success": true,
        "returnValue": null,
        "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "error": null,
        "logs": []
}

We have now deployed the contract and verified the contract address, in this instance we can see that the address is PWyA6fYiGFbJxaLqpPq3aSyGkHw9QNv9kY.

Calling the SayHello() method

We are going to call the SayHello() method, to do this we need to interact with the contract.

curl -X POST "http://localhost:38223/api/contract/PWyA6fYiGFbJxaLqpPq3aSyGkHw9QNv9kY/method/SayHello" -H "accept: application/json" -H "GasPrice: 100" -H "GasLimit: 100000" -H "Amount: 0" -H "FeeAmount: 0.01" -H "WalletName: cirrusdev" -H "WalletPassword: password" -H "Sender: P9zz49VdoPrirKhU2DBytwVTdCupcR4wYh" -H "Content-Type: application/json" -d "{}"

Note

It’s important that we specify the newContractAddress in the URI and use an address that has a sufficient balance for the sender paramater.

The response will tell us if the call was successfull and will also provide us with a Transaction ID to query.

{
        "fee": 11000000,
        "hex": "0100000002088b9aee9e7e1f824678b90d034ab4bef6f4745fda3b5085c5a01e165ed7ca96000000006a47304402202fdb8e52a4d4543206b64c3860f0f46c92b3f02733e6f95284e763a9261d4fd902207f65c8ff1ab2b5b96820b4caa6a7d3e9643f5aa04c8935f2336049727683b93f012102d8d7e4e8c427038596e69f4ce944986eeeb1fc3eb7327fe7b39d71eb6b72f0a2ffffffff6096e216aeb1b12a4fe8b4fd7c7f05490d53cb6ca56cc391d88b1b9170d7bbb4010000006a4730440220309a929541f1680108c758a8af789e82cfe45cce0a13787f4c694752a07de651022020c9ffe6454cef09b7479f44a9f0af798c7fee47ddbdad5d283de60a931ab475012102d8d7e4e8c427038596e69f4ce944986eeeb1fc3eb7327fe7b39d71eb6b72f0a2ffffffff0200b60300000000001976a914bf64d5ee5f797568ac5624053fda4a9ee52a5e3f88ac000000000000000034c1010000006400000000000000a086010000000000ab687f2579fe17d447e20c6d188590a766dd9a54ca8853617948656c6c6f8000000000",
        "message": "Your CALL method SayHello transaction was successfully built.",
        "success": true,
        "transactionId": "67c707f5e85029e9f38586e28caed900b4653cc04db2d8c76780197472287a84"
}

From the above we can see that the call was successfull and we have been provided a Transaction ID. Pass this Transaction ID as a paramater to the /SmartContracts/receipt endpoint.

curl -X GET "http://localhost:38223/api/SmartContracts/receipt?txHash=67c707f5e85029e9f38586e28caed900b4653cc04db2d8c76780197472287a84" -H "accept: application/json"

The response from the above will give us a summary of the transaction but also a response from the call that was made.

{
        "transactionHash": "67c707f5e85029e9f38586e28caed900b4653cc04db2d8c76780197472287a84",
        "blockHash": "67e058904b32ad9546713788105d0d5d2d7283a0e317adfad522e59f51e749b6",
        "postState": "1bed6aa13b7eb3a8714a2c81bde8c7442afbb8695a9cb3be6f59f216bbc90617",
        "gasUsed": 10038,
        "from": "P9zz49VdoPrirKhU2DBytwVTdCupcR4wYh",
        "to": "PWyA6fYiGFbJxaLqpPq3aSyGkHw9QNv9kY",
        "newContractAddress": null,
        "success": true,
        "returnValue": "Hello World!",
        "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "error": null,
        "logs": []
}

Hello World! is returned from the call, as expected.

Now we have deployed a basic HellowWorld contract, we can now look at extending the functionality.