WRC30
is a Token standard for digital assets based on the underlying wiki chain 2.0. Will replace the WRC20
contract token standard
[WRC30 Token Standard] (../wrc30)
智能合同开发 : WRC20 Sample
Contract source
WRC20.lua
Mylib = require "mylib"
-------------------------------------------------- ----------------------------------
_G.Config={
-- the waykichain contract stardard, if you do not know the waykichain stardard, please do not change it.
Standard = "WRC20",
-- the contract ownder address, please update it with the actual contract owner address.
Owner = "wcx5YzSHg6EqHEhcTjPTxtfPRRGAN7oQhd",
-- the contract name, please update it with the actual contract name.
Name = "WRC20N",
-- the contract symbol, please update it with the actual contract symbol.
Symbol = "WRC20S",
-- the number of decimals the token uses must be 8.
-- means to divide the token amount by 100000000 to get its user representation.
Decimals = 8,
-- the contract coin total supply, please update it with the actual contract symbol.
-- note: the Maximum issued totalSupply is 90000000000 * 100000000
totalSupply = 210000000 * 100000000
}
-------------------------------------------------- ----------------------------------
-- internal method and table
_G.LibHelp={
StandardKey={
Standard = "standard",
Owner = "owner",
Name = "name",
Symbol = "symbol",
Decimals = "decimals",
totalSupply = "totalSupply",
},
OP_TYPE = {
ADD_FREE = 1,
SUB_FREE = 2
},
ADDR_TYPE = {
REGID = 1,
BASE58 = 2
},
TableIsNotEmpty = function (t)
Return _G.next(t) ~= nil
End,
Unpack = function (t,i)
i = i or 1
If t[i] then
Return t[i], _G.LibHelp.Unpack(t,i+1)
End
End,
LogMsg = function (msg)
Local logTable = {
Key = 0,
Length = string.len(msg),
Value = msg
}
_G.mylib.LogPrint(logTable)
End,
GetContractValue = function (key)
Assert(#key > 0, "Key is empty")
Local tValue = { _G.mylib.ReadData(key) }
If _G.LibHelp.TableIsNotEmpty(tValue) then
Return true, tValue
Else
_G.LibHelp.LogMsg("Key not exist")
Return false,nil
End
End,
GetContractTxParam = function (startIndex, length)
Assert(startIndex > 0, "GetContractTxParam start error(<=0).")
Assert(length > 0, "GetContractTxParam length error(<=0).")
Assert(startIndex+length-1 <= #_G.contract, "GetContractTxParam length ".. length .." exceeds limit: " .. #_G.contract)
Local newTbl = {}
For i = 1, length do
newTbl[i] = _G.contract[startIndex+i-1]
End
Return newTbl
End,
WriteAppData = function (opType, moneyTbl, userIdTbl)
Local appOperateTbl = {
operatorType = opType,
outHeight = 0,
moneyTbl = moneyTbl,
userIdLen = #userIdTbl,
userIdTbl = userIdTbl,
fundTagLen = 0,
fundTagTbl = {}
}
Assert(_G.mylib.WriteOutAppOperate(appOperateTbl), "WriteAppData: ".. opType .." op err")
End,
GetFreeTokenCount = function (accountTbl)
Local freeMoneyTbl = { _G.mylib.GetUserAppAccValue( {idLen = #accountTbl, idValueTbl = accountTbl} ) }
Assert(_G.LibHelp.TableIsNotEmpty(freeMoneyTbl), "GetUserAppAccValue error")
Return _G.mylib.ByteToInteger(_G.LibHelp.Unpack(freeMoneyTbl))
End,
TransferToken = function (fromAddrTbl, toAddrTbl, moneyTbl)
Local money = _G.mylib.ByteToInteger(_G.LibHelp.Unpack(moneyTbl))
Assert(money > 0, money .. " <=0 error")
Local freeMoney = _G.LibHelp.GetFreeTokenCount(fromAddrTbl)
Assert(freeMoney >= money, "Insufficient money to transfer in the account.")
_G.LibHelp.WriteAppData(_G.LibHelp.OP_TYPE.SUB_FREE, moneyTbl, fromAddrTbl)
_G.LibHelp.WriteAppData(_G.LibHelp.OP_TYPE.ADD_FREE, moneyTbl, toAddrTbl)
End,
GetCurrTxAccountAddress = function ()
Return {_G.mylib.GetBase58Addr(_G.mylib.GetCurTxAccount())}
End
}
-- contract method for caller
_G.ICO={
TX_TYPE =
{
CONFIG = 0x11,
SEND_ASSET = 0x16,
},
Transfer=function (toTbl, valueTbl)
Local base58Addr = _G.LibHelp.GetCurrTxAccountAddress()
Assert(_G.LibHelp.TableIsNotEmpty(base58Addr),"GetBase58Addr error")
_G.LibHelp.TransferToken(base58Addr, toTbl, valueTbl)
End,
Config=function ()
-- check contract statu
Assert(_G.LibHelp.GetContractValue("name")==false,"Already configured")
-- write down standard key
For k,v in pairs(_G.LibHelp.StandardKey) do
If _G.Config[k] then
Local value = {}
If type(_G.Config[k]) == "number" then
Value = {_G.mylib.IntegerToByte8(_G.Config[k])}
Else
Value = {string.byte(_G.Config[k],1,string.len(_G.Config[k])) }
End
Local writOwnerTbl = {
Key = v,
Length = #value,
Value = value
}
Assert(_G.mylib.WriteData(writOwnerTbl),'can not issue tokens, failed to write the key='..v..' value='.._G.Config[k])
Else
Error('can not issue tokens, failed to read the key='..k)
End
End
-- issue tokens
Local totalSupplyTbl = {_G.mylib.IntegerToByte8(_G.Config.totalSupply)}
_G.LibHelp.WriteAppData(_G.LibHelp.OP_TYPE.ADD_FREE, totalSupplyTbl,{string.byte(_G.Config.owner,1,string.len(_G.Config.owner))})
_G.LibHelp.LogMsg("contract config success, name: ".._G.Config.name.."issuer: ".._G.Config.owner)
End
}
-------------------------------------------------- ----------------------------------
Assert(#_G.contract >=4, "Parameter length error (<4): " ..#_G.contract)
Assert(_G.contract[1] == 0xf0, "Parameter MagicNo error (~=0xf0): " .. _G.contract[1])
If _G.contract[2] == _G.ICO.TX_TYPE.CONFIG then
_G.ICO.Config()
Elseif _G.contract[2] == _G.ICO.TX_TYPE.SEND_ASSET and #_G.contract==2+2+34+8 then
Local pos = 5
Local toTbl = _G.LibHelp.GetContractTxParam(pos, 34)
Pos = pos + 34
Local valueTbl = _G.LibHelp.GetContractTxParam(pos, 8)
_G.ICO.Transfer(toTbl, valueTbl)
Else
Error(string.format("Method %02x not found or parameter error", _G.contract[2]))
End
```
## Publishing smart contracts
* Smart contracts can be issued at any address, and smart contract publishers are not necessarily the owner of the contract.
|Used API| Description|
| :---: | :--- |
| submitcontractdeploytx | for publishing smart contracts |
**Example**
```json
curl -u Waykichain:admin -d '{"jsonrpc":"2.0","id":"curltext","method":"submitcontractdeploytx","params":["wcx5YzSHg6EqHEhcTjPTxtfPRRGAN7oQhd","/tmp/lua/wrc20 .lua",110000000]}' -H 'content-type:application/json;' http://127.0.0.1:6967
{
"result": {
"txid": "b2d2054efb55eaa89be3d6293c46369d0f532f595cda655619caf4ec04550a36"
},
"error": null,
"id": "curltext"
}
```
## Query the regid of the smart contract
|Used API| Description|
| :---: | :--- |
Getcontractregid | Query the contract's `regid` by issuing the trade hash generated when the smart contract is issued
**Example**
```json
curl -u Waykichain:admin -d '{"jsonrpc":"2.0","id":"curltext","method":"getcontractregid","params":["b2d2054efb55eaa89be3d6293c46369d0f532f595cda655619caf4ec04550a36"]}' -H 'content- Type:application/json;' http://127.0.0.1:6967
{
"result": {
"regid": "50709-2",
"regid_hex": "15c600000200"
},
"error": null,
"id": "curltext"
}
```
## Calling the contract to activate the token
|Used API| Description|
| :---: | :--- |
| submitcontractcalltx | Call contract to activate tokens |
According to ** [parameter description of smart contract call] (../develop_guide/) ** call contract parameters
+--------+--------------+-------+ Magic number + specified contract method | Reserved bits | "f0110000" = +--------+--------------+-------+ | 0xf0 | 0x11 | 0000 | +--------+--------------+-------+
**Example**
```json
curl -u Waykichain:admin -d '{"jsonrpc":"2.0","id":"curltext","method":"submitcontractcalltx","params":["wcx5YzSHg6EqHEhcTjPTxtfPRRGAN7oQhd","50709-2"," F0110000",0,1000000]}' -H 'content-type:application/json;' http://127.0.0.1:6967
{
"result": {
"txid": "28514c71212a9cc59fd6054a32c1ccdb2cb5a43a4043f10be1c779eda0fd93a5"
},
"error": null,
"id": "curltext"
}
Get the contract owner
Used API | Description |
---|---|
Getcontractdata | Get Smart Contract Related Data Information |
Example
curl -u Waykichain:admin -d '{"jsonrpc":"2.0","id":"curltext","method":"getcontractdata","params":["50709-2","owner",false ]}' -H 'content-type:application/json;' http://127.0.0.1:6967
{
"result": {
"contract_regid": "50709-2",
"key": "owner",
"value": "wcx5YzSHg6EqHEhcTjPTxtfPRRGAN7oQhd"
},
"error": null,
"id": "curltext"
}
Check contract owner token total
Used API | Description |
---|---|
getcontractaccountinfo | Query the number of coins in a contract with a contract |
Example
curl -u Waykichain:admin -d '{"jsonrpc":"2.0","id":"curltext","method":"getcontractaccountinfo","params":["50709-2","wcx5YzSHg6EqHEhcTjPTxtfPRRGAN7oQhd"]} ' -H 'content-type:application/json;' http://127.0.0.1:6967
{
"result": {
"account_uid": "77637835597a53486736457148456863546a505478746650525247414e376f516864",
"free_value": 21000000000000000,
"frozen_funds": []
},
"error": null,
"id": "curltext"
}
Transferring tokens
Used API | Description |
---|---|
submitcontractcalltx | Create a contract transaction when calling a contract |
Call the parameters of the contract according to [parameter description of smart contract call] (./develop_guide.md/)
example
"f0160000774e5057717639627646436e4d6d3164646951644837665577556b3251677273324e0010a5d4e8000000" =
+--------------+---------------------+------------ ----+--------------------------------------------- ------------------------+------------------------- ------+
| magic number (1 byte) + specified contract method (1 byte) + reserved bit (2 bytes) + receiver: wNPWqv9bvFCnMm1ddiQdH7fUwUk2Qgrs2N (34 bytes) + amount: 10000 token (8 bytes) |
+--------------+---------------------+------------ ----+--------------------------------------------- ------------------------+------------------------- ------+
0xf0 | 0x16 | 0000 |774e5057717639627646436e4d6d3164646951644837665577556b3251677273324e | 0010a5d4e8000000 |
+--------------+---------------------+------------ ----+--------------------------------------------- ------------------------+------------------------- ------+
Example
curl -u Waykichain:admin -d '{"jsonrpc":"2.0","id":"curltext","method":"submitcontractcalltx","params":["wcx5YzSHg6EqHEhcTjPTxtfPRRGAN7oQhd","50709-2"," F0160000774e5057717639627646436e4d6d3164646951644837665577556b3251677273324e0010a5d4e8000000",0,1000000]}' -H 'content-type:application/json;' http://127.0.0.1:6967
{
"result": {
"txid": "7000a083a12369aa803d629b1ca8fa2211c605c471f7e858aa5466150b1e2b06"
},
"error": null,
"id": "curltext"
}
Confirm whether the recipient’s token has arrived
Example
curl -u Waykichain:admin -d '{"jsonrpc":"2.0","id":"curltext","method":"getcontractaccountinfo","params":["50709-2","wNPWqv9bvFCnMm1ddiQdH7fUwUk2Qgrs2N"]} ' -H 'content-type:application/json;' http://127.0.0.1:6967
{
"result": {
"account_uid": "774e5057717639627646436e4d6d3164646951644837665577556b3251677273324e",
"free_value": 1000000000000,
"frozen_funds": []
},
"error": null,
"id": "curltext"
}