Hello World
Smart Contracts Quick Start Guide
WaykiChain DAPP Foundation
A blockchain can be abstracted into a state machine that is synchronized across the network. A smart contract is code that executes on a blockchain system and changes the state in the state machine through transactions. Due to the characteristics of the blockchain, the call of the smart contract can be guaranteed to be serial and globally consistent.
WaykiChain smart contract currently supports Lua
language development, and does not support multi-contract calls. [Learning Lua Language] (https://www.runoob.com/lua/lua-basic-syntax.html)
Key words
Keywords | Description |
---|---|
contract | The default global variable name inside the smart contract, used to get external call parameters inside the smart contract, type is table |
mylib | Smart Contract Internal API Interface |
[Common Methods] (./common_func.md) | Common Methods for Smart Contract Development, Based on Lua Language |
[mylib use case] (./api_debug.md) | Common use cases based on mylib package |
WaykiMix | Smart Contract Development Online IDE |
WaykiBridge | DAPP Wallet Interface Unification Tool |
BaaS | WaykiChain Blockchain Public API |
Debug environment configuration
WaykiChain smart contract development and deployment environment support [WaykiMix] (../DeveloperHelper/waykimix.md) online deployment and call, build [local test network node] (../NodeDeployment/testnet.md) can be more convenient debug.
Smart contract basic structure
demo.lua
Mylib = require "mylib"
Main = function()
End
Main()
Helloworld Smart Contract Source
The entry to the smart contract is the Main
function, and the Main
function contains two different functional methods.
SayHelloToLog()
is used to output Hello World!
in the log.
SaveHelloToChain()
is used to write Hello
-World
to LevelDB
in the blockchain as key-value
, which can be found in BaaS Query the corresponding value.
Mylib = require "mylib"
-- The script must start with `mylib = require "mylib"`. Be sure to put it in the first line. If the first line is left blank, an exception will be reported.
--Define contract call events
METHOD = {
SAYHELLOTOLOG = 0x17,
SAVEHELLOTOCHAIN = 0x18
}
LOG_TYPE =
{
ENUM_STRING = 0,
ENUM_NUMBER = 1
}
-- used to output log information to a file
LogMsg = function(LogType, Value)
Local LogTable = {
Key = 0, --log type: string or number
Length = 0, the total length of the --value data stream
Value = nil -- string or number stream
}
--Save data stream
LogTable.key = LogType
LogTable.length = #Value
LogTable.value = Value
mylib.LogPrint(LogTable)
End
-- Write key-value key-value pairs to the blockchain
WriteStrkeyValueToDb = function (Strkey, ValueTbl)
Local t = type(ValueTbl)
Assert(t == "table","the type of Value isn't table.")
Local writeTbl = {
Key = Strkey,
Length = #ValueTbl,
Value = {}
}
writeTbl.value = ValueTbl
If not mylib.WriteData(writeTbl) then error("WriteData error") end
End
-- Get information about the calling contract
-- The parameter startIndex is the starting index, the length is the length of the obtained field, and the contract is a global variable.
-- return contract with startIndex as the starting index, length for the length of the contract part of the field
GetContractTxParam = function (startIndex, length)
Assert(startIndex > 0, "GetContractTxParam start error(<=0).")
Assert(length > 0, "GetContractTxParam length error(<=0).")
Assert(startIndex+length-1 <= #contract, "GetContractTxParam length ".. length .." exceeds limit: " .. #contract)
Local newTbl = {}
Local i = 1
For i = 1, length do
newTbl[i] = contract[startIndex+i-1]
End
Return newTbl
End
-------------------------------------------------- -
SayHelloToLog = function()
LogMsg(LOG_TYPE.ENUM_STRING,"Hello World!")
End
SaveHelloToChain = function(contextTbl)
WriteStrkeyValueToDb("Hello", contextTbl)
LogMsg(LOG_TYPE.ENUM_STRING,"Save Hello To Chain Successfully!")
End
--Smart contract entry
Main = function()
Assert(#contract >=4, "Param length error (<4): " ..#contract )
Assert(contract[1] == 0xf0, "Param MagicNo error (~=0xf0): " .. contract[1])
If contract[2] == METHOD.SAYHELLOTOLOG then
SayHelloToLog()
Elseif contract[2] == METHOD.SAVEHELLOTOCHAIN then
Local contextTbl = GetContractTxParam(5,5)--Get the information of the calling contract == "World"
SaveHelloToChain(contextTbl)
Else
Error('method# '..string.format("%02x", contract[2])..' not found')
End
End
Main()
Deploying smart contracts
Deploy to test network via WaykiMix
Deploy to the test network via the local node RPC submitcontractdeploytx
// Request
Curl -u Waykichain:admin -d '{"jsonrpc":"2.0","id":"curltext","method":"submitcontractdeploytx","params":["wLWxCRWDTb3fUTa6ztoTTCzFwDqzbckSJ7","/tmp/lua/helloworld .lua",110000000]}' -H 'content-type:application/json;' http://127.0.0.1:6967
// Response
{
"result":
{
"hash":"dfdb78278c486016a8588c6ac525eced4348725f5a85af51c898fed320e72e23"
},
"error": null,
"id": "curltext"
}
Query smart contract regid
Query smart contract regid by WaykiMix
Query smart contract regid via local node RPC getcontractregid
// Request
Curl -u Waykichain:admin -d '{"jsonrpc":"2.0","id":"curltext","method":"getcontractregid","params":["dfdb78278c486016a8588c6ac525eced4348725f5a85af51c898fed320e72e23"]}' -H 'content- Type:application/json;' http://127.0.0.1:6967
// Response
{
"result":
{
"regid:":"320561-1",
"regid_hex" : "31e404000100"
},
"error": null,
"id": "curltext"
}
Calling Smart Contract 1
Here the contract is passed in the parameter f0170000
. According to the contract source, the SayHelloToLog()
method is called, ie `Hello World!" is printed in the log.
[Parameter Description for Smart Contract Call] (./develop_guide.md/)
Parameter parsing of the calling contract
+--------+--------------+-------+
Magic number + specified contract method | Reserved bits |
"f0170000" = +--------+--------------+-------+
| 0xf0 | 0x17 | 0000 |
+--------+--------------+-------+
Calling Smart Contracts via WaykiMix
Calling a smart contract via the local node RPC submitcontractcalltx
// Request
Curl -u Waykichain:admin -d '{"jsonrpc":"2.0","id":"curltext","method":"submitcontractcalltx","params":["wLWxCRWDTb3fUTa6ztoTTCzFwDqzbckSJ7","320561-1",0 ,"f0170000",1000000]}' -H 'content-type:application/json;' http://127.0.0.1:6967
// Response
{
"result":
{
"hash":"f867200b3d91fd2cbf8b0d8b8840e64bf620f08923acc3126fb960dd04b3064f"
},
"error": null,
"id": "curltext"
}
View log
The premise is to add debug=vm
to the local node WaykiChain.conf
to view the vm.log
information in the corresponding directory.
The screenshot shows that the log information is the running content of the Check method in the contract, that is, output Hello World!
information to the vm.log
file.
Calling Smart Contract 2
Here the contract is passed in the parameter f0180000576f726c64
, and the SAVEHELLOTOCHAIN()
method is called according to the contract source.
The 5 bytes of the parameters of the calling contract are taken as the value
value, and "Hello" is written as the key
value in the LevelDB
of the blockchain.
[Parameter Description for Smart Contract Call] (./develop_guide.md/)
Parameter parsing of the calling contract
+--------+--------------+-------+------------+
Magic * The specified contract method | Reserved bits | "World" |
"f0180000576f726c64" = +--------+--------------+-------+------------+
0xf0 | 0x18 | 0000 | 576f726c64 |
+--------+--------------+-------+------------+
Calling Smart Contracts via WaykiMix
Calling a smart contract via the local node RPC submitcontractcalltx
// Request
Curl -u Waykichain:admin -d '{"jsonrpc":"2.0","id":"curltext","method":"callcontracttx","params":["wLWxCRWDTb3fUTa6ztoTTCzFwDqzbckSJ7","320561-1",0 ,"f0180000576f726c64",1000000]}' -H 'content-type:application/json;' http://127.0.0.1:6967
// Response
{
"result":
{
"hash":"f65fc179dd9056b06a4a843ee696afa115678bdad523440ae6facd98e7d61a9d"
},
"error": null,
"id": "curltext"
}