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"
}