WRC30 是基于维基链公链2.0 底层发行的数字资产的Token标准。将替代WRC20合约代币标准

WRC30 代币标准




























智能合约开发 : WRC20 Sample

合约源码

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

发布智能合约

  • 任何地址都可以发布智能合约,智能合约发布者不一定是合约的拥有者。
Used API Description
submitcontractdeploytx 用于发布智能合约

Example

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

查询智能合约的regid

Used API Description
getcontractregid 通过发布智能合约时产生的交易hash,来查询合约的regid

Example

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

调用合约对代币进行激活

Used API Description
submitcontractcalltx 调用合约对代币进行激活

根据 智能合约调用时参数说明 调用合约的参数

               +--------+--------------+-------+
               |  魔法数 + 指定的合约方法 | 保留位 |
"f0110000" =   +--------+--------------+-------+
               |  0xf0  |  0x11        | 0000  |
               +--------+--------------+-------+

Example

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

获取合约owner

Used API Description
getcontractdata 获取智能合约相关数据信息

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

检查合约owner代币总额

Used API Description
getcontractaccountinfo 查询地址在某个合约拥有币的数量

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

对代币进行转账

Used API Description
submitcontractcalltx 调用合约时创建合约交易

根据 智能合约调用时参数说明 调用合约的参数

example

"f0160000774e5057717639627646436e4d6d3164646951644837665577556b3251677273324e0010a5d4e8000000"  =
+--------------+---------------------+----------------+---------------------------------------------------------------------+-------------------------------+
|魔法数(1 byte)+ 指定的合约方法(1 byte)+ 保留位(2 bytes)+ receiver:wNPWqv9bvFCnMm1ddiQdH7fUwUk2Qgrs2N(34 bytes)               + 金额: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"
}

确认接收者代币是否到账

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