美文网首页HiBlock区块链社区区块链入门
铂链第5课 如何在BOTTOS上搭建第一个DAPP应用[C++程

铂链第5课 如何在BOTTOS上搭建第一个DAPP应用[C++程

作者: 笔名辉哥 | 来源:发表于2019-01-24 18:04 被阅读5次

    1,摘要

    本文在学习者已完成BOTTOS本地节点搭建,钱包创建的前提下,演示如何通过前端调用BOTTOS智能合约程序(C++程序)查询交易执行结果和SDK调用的方法。

    2, 实践内容

    2.1 本地节点已启动,账号已创建

    (1) 重启节点
    本文假设你已经按照《铂链第2课 如何部署节点并加入BOTTOS测试网络?》完成了本地开发环境的部署。
    如果重启虚拟机后,需要重启下本地节点。
    在命令框进入BOTTOS安装目录,启动本地节点:./bottos --delegate=bottos --enable-wallet

    【成功执行结果】

    duncanwang@ubuntu64bit-server:~$ cd ~/go/src/github.com/bottos
    duncanwang@ubuntu64bit-server:~/go/src/github.com/bottos$ ./bottos --delegate=bottos --enable-wallet
    InsertBlock, number:6641, time:2019-01-06 10:55:27, delegate:bottos, trxn:0, hash:8af243f169b361c142a20f15fa45c47046406c60ba3ad3a9c168b41ec3e63e82, prevHash:b79a5c31a75333f357ddaeb98ed5d29b30655378d2f503d74c179c1551ee390e, version:1.0.0
    InsertBlock, number:6642, time:2019-01-06 10:55:30, delegate:bottos, trxn:0, hash:b11bf02f345cbc95d330154080e7a4638026dda1693167e900138f18d3507ef4, prevHash:8af243f169b361c142a20f15fa45c47046406c60ba3ad3a9c168b41ec3e63e82, version:1.0.0
    InsertBlock, number:6643, time:2019-01-06 10:55:33, delegate:bottos, trxn:0, hash:4b7c0b9195d1fec055d2e3f71276f988a887fae8cd069db2ef531738f8b6937d, prevHash:b11bf02f345cbc95d330154080e7a4638026dda1693167e900138f18d3507ef4, version:1.0.0
    ...
    

    (2)已创建账户信息
    本文假设你已经按照《铂链第3课 BOTTOS账户体系(密钥对/账号/钱包)的创建和管理》完成了账号的创建。没有创建好账号的参考该文完成账号创建。

    【账户信息】
    (1)账号名称:wangdenghui
    密钥对:
    public_key: 04692be71819302246bcfde268ff0e697d11a9493eac9f8cda1a0f0482fd1e87583d5844f072b0abfd43ffbd33ef804e19e148ca5c1518fd0f01bbc4b63cb7c6ae
    private_key: e78c1801ca06099552afa86ea2ca38bd12fc8e5a8e817c3211074ab652c66ddf
    账户余额:800BTO
    质押情况:100 BTO for time
    100 BTO for space

    (2)账号名称:bottos
    密钥对:
    PrivateKey = "b799ef616830cd7b8599ae7958fbee56d4c8168ffd5421a16025a398b8a4be45"
    PublicKey = "0454f1c2223d553aa6ee53ea1ccea8b7bf78b8ca99f3ff622a3bb3e62dedc712089033d6091d77296547bc071022ca2838c9e86dec29667cf740e5c9e654b6127f"

    账户余额:936000000BTO
    质押情况:0 BTO for time
    0 BTO for space

    输入以下命令可查看核实账户信息
    【执行结果】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli account get --account wangdenghui
    
        Account: wangdenghui
        Balance: 800.00000000 BTO
        Pubkey: 049b98b5f5eea7fd5145842d08f8cd25052f69e731f9f550ac8a2e37792e165cf13fbc52ad7dad32eaa192799601b4cc35eab1923e007048f9d47c80aa4bf9cb8d
    
        StakedBalance: 0.00000000 BTO
        UnStakingBalance: 0.00000000 BTO
        StakedSpaceBalance: 100.00000000 BTO
        StakedTimeBalance: 100.00000000 BTO
        UnStakingTimestamp: 0
    
        AvailableSpaceBalance: 151142400440
        UsedSpaceBalance: 360
        AvailableTimeBalance: 28800000242
        UsedTimeBalance: 158
    
        UnClaimedReward: 0.00000000 BTO
    
        Vote: N/A
    
        Contracts: N/A  
    

    【方法提醒】
    如果已把bcli复制到系统bin文件夹,则直接执行bcli ...,如果是复制到工作目录,则需要输入./bcli格式。 辉哥选择了第2种。

    (1)复制bcli命令到本地工程目录
    cp /home/duncanwang/go/src/github.com/bottos/bcli .

    (2)复制到可执行文件夹:
    cp /home/duncanwang/go/src/github.com/bottos/bcli /usr/bin/.

    2.2 需求描述和智能合约代码分析

    2.2.1 智能合约代码

    (1)testRegUser.hpp

    #define USER_NAME_LEN (20)
    #define USER_INFO_LEN (20)
    
    
    
    extern "C" {
        int reguser();
    }
    
    //@abi action reguser
    struct UserInfo {
        char userName[USER_NAME_LEN];
        char userInfo[USER_INFO_LEN];
    };
    
    
    //@abi table userinfo:[index_type:string, key_names:userName, key_types:string]
    struct UserBaseInfo {
        char userInfo[USER_INFO_LEN];
    };
    
    

    (2)testRegUser.cpp

    #include "contractcomm.hpp"
    #include "testRegUser.hpp"
    
    
    #define PARAM_MAX_LEN (2048)
    
    #define ERROR_PACK_FAIL (1)
    #define ERROR_UNPACK_FAIL (2)
    #define ERROR_SAVE_DB_FAIL (3)    
    
    
    static bool unpack_struct(MsgPackCtx *ctx, UserInfo *info)
    { 
        uint32_t size = 0;
        UNPACK_ARRAY(2)
        
        UNPACK_STR(info, userName, (USER_NAME_LEN+1))
        UNPACK_STR(info, userInfo, (USER_INFO_LEN+1))
        
        return true;
    }
    
    static bool pack_struct(MsgPackCtx *ctx, UserBaseInfo *info)
    {   
        PACK_ARRAY16(1)
        PACK_STR16(info, userInfo )
    
        return true;
    }
    
    int reguser() 
    {
        UserInfo userinfo = {{0}};
        
        if ( !parseParam<UserInfo>(userinfo) )  return ERROR_UNPACK_FAIL;
    
        myprints(userinfo.userName);
        myprints(userinfo.userInfo);
    
        UserBaseInfo userBaseInfo = {{0}};
        
        strcpy(userBaseInfo.userInfo, userinfo.userInfo);
    
        char tablename[] = "userinfo"; 
    
        if (!saveData(userBaseInfo, tablename, userinfo.userName)) return ERROR_SAVE_DB_FAIL;
                
        return 0;      
    
    }
    

    2.2.2 前端代码

    (3) index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=375px, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Bottos Demo</title>
        <script src="http://unpkg.com/bottos-sdk-js"></script>
        <script src="./index.js"></script>
    </head>
    <body>
        <div style="margin-top:50px">
            <button style="width:100px;height:30px;background-color:bisque" onClick="getTransaction()" >查询合约结果</button>
            <button style="width:100px;height:30px;background-color:coral" onClick="pushTransaction()">运行合约</button>
            <button style="width:100px;height:30px;background-color:coral" onClick="createAccount()">创建账户</button>
           
        </div>
    
    
        <div style="margin-top:100px">
            <p>创建账户执行结果</p>
            <div id="createAccount" style="min-height:150px;background-color:#ccc">
    
            </div>
        
            <p>运行合约执行结果</p>
            <div id="pushTransaction" style="min-height:150px;background-color:#ccc">
        
            </div>
        
            <p>查询合约执行结果</p>
            <div id="getTransaction" style="min-height:150px;background-color:#ccc">
        
            </div>
        </div>
        
    </body>
    </html>
    

    (4)index.js

    var BottosWalletSDK = window.BottosWalletSDK
    
    /* 此处更改为要调用的节点或者本地节点的IP地址 */
    /*
    const config = {
        baseUrl:'http://42.159.154.130:8689/v1',
    }
    */
    const config = {
        baseUrl:'http://192.168.1.105:8689/v1',
    }
    
    var SDK = new BottosWalletSDK(config)
    var Tool = SDK.Tool
    var Wallet = SDK.Wallet
    var Contract = SDK.Contract
    var Api = SDK.Api
    
    /* 创建密钥对 */
    const keys = Wallet.createKeys()
    console.log({privateKey:keys.publicKey})
    
    let account = 'testaccount'
    let password = 'TestPassword1'/* 账号要求为至少有一个大小写,长度为6~20。2月底版本修改 */
    let keystore = null
    let publicKey = keys.publicKey
    
    /* 创建账号,目前必须有推荐人,还要有推荐人私钥,存在私钥泄露风险。 */
    function createAccount(){
        console.log("createAccount")
        let params = {
            account:account,
            password:password,
            publicKey:publicKey
        }
    
        let referrerInfo = {
            account:"wangdenghui",
            privateKey:"e78c1801ca06099552afa86ea2ca38bd12fc8e5a8e817c3211074ab652c66ddf"
        }
        Wallet.createAccountWithIntro(params,referrerInfo)
            .then(response=>{
                keystore = response
                console.log({response})
                document.getElementById('createAccount').innerHTML = JSON.stringify(response)
            }).catch(error=>{
                console.log({error})
                document.getElementById('createAccount').innerHTML = JSON.stringify(error)
                
            })
    }
    
    /* 调用合约,目前采用wangdenghui本地账号,存在私钥泄露可能 */
    function callContract(){
        let params = {
            method:'reguser',
            contract:'reguser@wangdenghui',
            sender:"wangdenghui",
            param:{
                userName:'duncan2',
               // userInfo:JSON.stringify({phone:'110120',age:18})
               userInfo:'GreatMan'
            }
        }
    
        let privateKeyStr = "e78c1801ca06099552afa86ea2ca38bd12fc8e5a8e817c3211074ab652c66ddf"
    
        Contract.callContract(params,privateKeyStr)
            .then(response=>{
                console.log({response})
                document.getElementById('pushTransaction').innerHTML = JSON.stringify(response)
            }).catch(error=>{
                console.log({error})
                document.getElementById('pushTransaction').innerHTML = JSON.stringify(error)
            })
    }
    
    function pushTransaction(){
        console.log("pushTransaction")
        callContract()
    }
    
    /* 获取交易记录 */
    function getTransaction(){
        console.log("getTransaction")
        let url =  config.baseUrl + '/common/query'
        let params = {
            contract:'reguser@wangdenghui',
            object:'userinfo',
            key:'duncan'
    
        }
    
        fetch(url,{
            method:'POST',
            body:JSON.stringify(params)
        }).then(function(response){return response.json()})   
        .then(function(response){
            document.getElementById('getTransaction').innerHTML = JSON.stringify(response)
        }).catch(function(error){
            document.getElementById('getTransaction').innerHTML = JSON.stringify(error)
        })
    }
    

    2.2.3 配置代码

    (5)package.json

    {
      "name": "testRegUser",
      "version": "1.0.0",
      "description": "my first DAPP on BOTTOS chain!",
      "main": "",
      "directories": {
        "test": "test"
      },
      "scripts": {
        "dev": "lite-server",
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "lite-server": "^2.4.0"
      }
    }
    

    完整的工程文件请加入辉哥的知识星球获取。


    2.2.2 智能合约编译和部署

    (1)编译产生WASM和wast文件
    Web Assembly(WASM)就是一种中间代码(字节码)技术。突出的特点就是精简,加载时间短以及高速的执行模型。其他高级语言(C/C++等)编写的程序都可以编译成WASM格式的程序。这样的好处是WASM可以兼容运行所有用C/C++等高级语言编写的程序。
    以Bottos虚拟机举例,首先由高级语言C/C++编写的智能合约,经过编译生成wast文件,再转换成wasm的字节码格式,再由虚拟机加载wasm字节码文件,解析其中的字节码,转换成对应的方法执行。
    另外,wast/wasm可以相互转换,参考:https://github.com/WebAssembly/wabt

    python ../gentool.py --type wasm --file testRegUser.cpp

    【成功执行结果】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ python ../gentool.py --type wasm --file testRegUser.cpp
    ../bin/clang -emit-llvm -O3 --std=c++14 --target=wasm32 -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -I ../lib -I . -c testRegUser.cpp -o ./tmpdir/build/testRegUser.cpp
    In file included from testRegUser.cpp:1:
    ../lib/contractcomm.hpp:181:22: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]
                myprints("ERROR: Get my contract name failed.");
                         ^
    ../lib/contractcomm.hpp:196:18: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]
            myprints("getBinValue failed!");
                     ^
    2 warnings generated.
    ../bin/llvm-link -o ./tmpdir/linked.bc ./tmpdir/build/*
    ../bin/llc --asm-verbose=false -o ./tmpdir/assembly.s ./tmpdir/linked.bc
    ../bin/s2wasm -o testRegUser.wast -s 16384 ./tmpdir/assembly.s
    

    (2)编译产生ABI文件

    python ../gentool.py --file testRegUser.hpp

    【运行结果】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ python ../gentool.py --file testRegUser.hpp
    
    [ testRegUser.abi ] is generated. Please have a check.
    

    (3)部署智能合约与ABI文件

    bcli contract deploy --contract reguser --account wangdenghui --code testRegUser.wasm --abi testRegUser.abi
    【成功执行结果】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli contract deploy --contract reguser --account wangdenghui --code testRegUser.wasm --abi testRegUser.abi
    
    TrxHash: 87c8f9506e28e7df808dd3b439095c8bfac38a91d27ac71fb9a7464964de3222
    
    This transaction is sent. Please check its result by command : bcli transaction get --trxhash  <hash>
    
    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli transaction get --trxhash  87c8f9506e28e7df808dd3b439095c8bfac38a91d27ac71fb9a7464964de3222
    {
        "ResourceReceipt": {
            "account_name": "wangdenghui",
            "space_token_cost": 8720,
            "time_token_cost": 100
        },
        "Transaction": {
            "contract": "bottos",
            "cursor_label": 356016816,
            "cursor_num": 10090,
            "lifetime": 1546846894,
            "method": "deploycontract",
            "param": {
                "contract": "reguser",
                "contract_abi": "7b0a09227479706573223a205b5d2c0a092273747275637473223a205b0a20202020202020202020202020207b0a202020202020202020202020202009226e616d65223a202255736572496e666f222c0a2020202020202020202020202020092262617365223a2022222c0a202020202020202020202020202009226669656c6473223a207b0a2020202020202020202020202020090922757365724e616d65223a2022737472696e67222c0a202020202020202020202020202009092275736572496e666f223a2022737472696e67220a20202020202020202020202020202020202020207d0a2020202020202020202020202020097d2c0a20202020202020202020202020207b0a202020202020202020202020202009226e616d65223a20225573657242617365496e666f222c0a2020202020202020202020202020092262617365223a2022222c0a202020202020202020202020202009226669656c6473223a207b0a202020202020202020202020202009092275736572496e666f223a2022737472696e67220a20202020202020202020202020202020202020207d0a2020202020202020202020202020097d0a202020202020205d2c0a0922616374696f6e73223a205b0a20202020202020202020202020207b0a20202020202020202020202020200922616374696f6e5f6e616d65223a202272656775736572222c0a2020202020202020202020202020092274797065223a202255736572496e666f220a20202020202020202020202020207d0a202020202020205d2c0a09227461626c6573223a205b0a20202020202020202020202020207b0a202020202020202020202020202009227461626c655f6e616d65223a202275736572696e666f222c0a20202020202020202020202020200922696e6465785f74797065223a2022737472696e67222c0a202020202020202020202020202009226b65795f6e616d6573223a20205b0a2020202020202020202020202020090922757365724e616d65220a202020202020202020202020202009205d2c0a202020202020202020202020202009226b65795f7479706573223a20205b0a2020202020202020202020202020090922737472696e67220a202020202020202020202020202009205d2c0a2020202020202020202020202020092274797065223a20225573657242617365496e666f220a20202020202020202020202020207d0a202020202020205d0a7d0a",
                "contract_code": "0061736d0100000001290760027f7f0060067f7f7f7f7f7f017f60027f7f017f60037f7f7f017f6000006000017f60017f017f023c0403656e7608676574506172616d000203656e76066d656d736574000303656e76067072696e7473000003656e760b73657442696e56616c7565000103060504050603020404017000000503010001073503066d656d6f72790200077265677573657200051e5f474c4f42414c5f5f7375625f495f74657374526567557365722e63707000040a9f1805f202004100420037028c4041004200370294404100420037029c40410042003702a440410042003702ac40410041003602b440410041003602b840410041003602bc40410041003602c040410041003602c440410041003602c840410041003602cc40410041003602d040410041003602d440410041003602d840410041003602dc40410041003602e040410041003602e440410041003602e840410041003602ec40410041003602f040410041003602f440410041003602f840410041003602fc404100410036028041410041003602844141004100360288414100410036028c414100410036029041410041003602944141004100360298414100410036029c41410041003602a041410041003602a441410041003602a841410041003602ac41410041003602b041410041003602b441410041003602b841410041003602bc41410041003602c041410041003602c441410041003602c841410041003602cc41410041003602d041410041003602d4410bb70201077f4100410028020441d0006b220636020441002102200641286a4100412810011a02400240200641286a1006450d00024020062d0028450d00200641286a4101722100410021050340200020056a2103200541016a2202210520032d00000d000b0b200641286a200210022006413c6a21004100210541002104024020062d003c450d002006413d6a2101410021030340200120036a2102200341016a2204210320022d00000d000b0b200020041002200641206a4100360200200641186a4200370300200642003703100340200641106a20056a200020056a2d000022033a0000200541016a210520030d000b2006410c6a41002d0088453a0000200641002900804537020441004103200641106a200641046a200641286a10071b21050c010b410221050b4100200641d0006a36020420050bc30401057f4100410028020441a0106b220536020441002104200541106a410041801010011a200541106a41801010002102200541003a0000200520023602082005410036020c2005200541106a3602040240200520054190106a1008450d0002400240024020052d0090104106470d00410021042005280298104102470d03200520054190106a1008450d0320052d0090104105470d01200528029810220141016a4116490d02200541013a00000c030b200541063a00000c020b200541063a00000c010b0240024020052802042203450d002005410c6a280200220220016a200541086a2802004d0d010b200541043a00000c010b02402001450d00200320026a210420002102200121030340200220042d00003a0000200241016a2102200441016a21042003417f6a22030d000b2005410c6a28020021020b41002104200020016a41003a00002005410c6a200220016a360200200520054190106a1008450d000240024020052d0090104105470d00200528029810220141016a4116490d01200541013a0000410021040c020b200541063a00000c010b0240024020052802042203450d002005410c6a280200220220016a200541086a2802004d0d010b200541043a0000410021040c010b02402001450d00200041146a2104200320026a2102200121030340200420022d00003a0000200441016a2104200241016a21022003417f6a22030d000b2005410c6a28020021020b2005410c6a200220016a360200200020016a41146a41003a0000410121040b4100200541a0106a36020420040bb60401077f410041002802044190106b220936020441002107200941106a410041801010011a200941013a0012200941dc013b0110024020002d00002203450d00200041016a2104410021060340200420066a2105200641016a2207210620052d00000d000b0b200941da013a0013200920073a001520092007410874418080fc07714110763a001402400240024002400240200741ffff03712206450d00200641066a22084180104d0d0141002106200941086a4100280098453602002009410029009045370200200941017221070340200720066a2105200641016a2204210620052d00000d000b2009200410020c030b410621080c010b200920033a001620064101460d00410120066b2107200041016a2106200941106a41077221050340200520062d00003a0000200541016a2105200641016a2106200741016a22070d000b0b4100210741002104024020012d0000450d00200141016a2100410021060340200020066a2105200641016a2204210620052d00000d000b0b024020022d0000450d00200241016a2100410021060340200020066a2105200641016a2207210620052d00000d000b0b410121062001200420022007200941106a200810030d01410021062009410e6a41002d00ae453a00002009410c6a41002f00ac453b0100200941086a41002800a845360200200941002900a045370200200941017221070340200720066a2105200641016a2204210620052d00000d000b2009200410020b410021060b410020094190106a36020420060bf20902047f017e0240024020002802042202450d00200028020c220341016a220420002802084d0d010b200041023a000041000f0b200220036a2d000021022000410c6a200436020002400240024002400240024002400240024002400240024002400240200241bb7e6a220241174b0d00024020020e18000101010101010203040501010101010101010101060107000b200141003a00000240200041046a2802002202450d002000410c6a2203280200220441026a2205200041086a2802004d0d080b200041073a000041000f0b200041063a000041000f0b200141013a00000240200041046a2802002202450d002000410c6a2203280200220441016a200041086a2802004d0d070b200041043a000041000f0b200141023a00000240200041046a2802002202450d002000410c6a2203280200220441026a200041086a2802004d0d070b200041043a000041000f0b200141033a00000240200041046a2802002202450d002000410c6a2203280200220441046a200041086a2802004d0d070b200041043a000041000f0b200141043a00000240200041046a2802002202450d002000410c6a2203280200220441086a200041086a2802004d0d070b200041043a000041000f0b200141053a00000240200041046a2802002202450d002000410c6a2203280200220441026a2205200041086a2802004d0d070b200041043a000041000f0b200141063a00000240200041046a2802002202450d002000410c6a2203280200220441026a2205200041086a2802004d0d070b200041043a000041000f0b200220046a22002d0000210220002d0001210020032005360200200141086a200220004108747222004118742000410874418080fc07717241107636020041010f0b200141086a200220046a2d00003a00002003200328020041016a36020041010f0b200141086a2200200220046a22022d00003a0000200141096a20022d00013a00002003200328020041026a360200200020002f010022014118742001410874418080fc0771724110763b010041010f0b200141086a2205200220046a22002d00003a0000200141096a20002d00013a00002001410a6a200041026a2d00003a00002001410b6a200041036a2d00003a00002003200328020041046a3602002005200528020022004118742000410874418080fc07717220004108764180fe03712000411876727236020041010f0b200141086a2205200220046a22002d00003a0000200141096a20002d00013a00002001410a6a200041026a2d00003a00002001410b6a200041036a2d00003a00002001410c6a200041046a2d00003a00002001410d6a200041056a2d00003a00002001410e6a200041066a2d00003a00002001410f6a200041076a2d00003a00002003200328020041086a360200200520052903002206423886200642288642808080808080c0ff0083842006421886428080808080e03f8320064208864280808080f01f838484200642088842808080f80f832006421888428080fc07838420064228884280fe0383200642388884848437030041010f0b200220046a22002d0000210220002d0001210020032005360200200141086a200220004108747222004118742000410874418080fc07717241107636020041010f0b200220046a22002d0000210220002d0001210020032005360200200141086a200220004108747222004118742000410874418080fc07717241107636020041010b0b43040041040b04b0620000004180c5000b0975736572696e666f00004190c5000b0c7061636b206661696c6564000041a0c5000b0f73617665206462206661696c656400",
                "vm_type": 1,
                "vm_version": 1
            },
            "sender": "wangdenghui",
            "sig_alg": 1,
            "signature": "8b7732622a45a0637eb2783bd785b038e2e3ba2662856588f7813c1725b021315e53b2a318d5b09bcdf9a7c6bd0e1fab264a8a954a922c4de90d4514c9fab9bf",
            "version": 65536
        },
        "TrxHash": "87c8f9506e28e7df808dd3b439095c8bfac38a91d27ac71fb9a7464964de3222"
    }
    
    <<<Transaction Status>>> : commited
    
    

    (4)运行合约
    bcli transaction push --sender wangdenghui --method reguser --contract reguser@wangdenghui --param "userName:duncan, userInfo:GoodMan"

    【执行成功结果】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli transaction push --sender wangdenghui --method reguser --contract reguser@wangdenghui --param "userName:duncan, userInfo:GoodMan"
    0 : {userName string} , KEY:  userName , VAL:  duncan
    1 : {userInfo string} , KEY:  userInfo , VAL:  GoodMan
    
    TrxHash: 95872bc215ec1afabb937536c0f71e5d4db704b518d9039bba67aba0538f96a9
    
    This transaction is sent. Please check its result by command : bcli transaction get --trxhash  <hash>
    
    
    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli transaction get --trxhash  95872bc215ec1afabb937536c0f71e5d4db704b518d9039bba67aba0538f96a9
    {
        "ResourceReceipt": {
            "account_name": "wangdenghui",
            "space_token_cost": 187,
            "time_token_cost": 165
        },
        "Transaction": {
            "contract": "reguser@wangdenghui",
            "cursor_label": 1180986307,
            "cursor_num": 10163,
            "lifetime": 1546847113,
            "method": "reguser",
            "param": {
                "userinfo": "GoodMan",
                "username": "duncan"
            },
            "sender": "wangdenghui",
            "sig_alg": 1,
            "signature": "fd21d873ba0cd0a8cf6ba5f756562eae5ae93354642bc52c7739c2bd1e80550f35bbb8278b106af39fdc2c0c46e72468675aeb071cb3600e5ecd39b9fcbb3d22",
            "version": 65536
        },
        "TrxHash": "95872bc215ec1afabb937536c0f71e5d4db704b518d9039bba67aba0538f96a9"
    }
    
    <<<Transaction Status>>> : commited
    

    界面截图:


    2.运行合约.png

    (5) 查看执行结果
    合约正确执行后,则保存至链上的数据userinfo和username分别是GoodMan和duncan,可以通过bcli gettable 命令进行查询,该命令成功后将返回BCLI发送的Transaction信息。

    参数说明:
    --contract 合约账户名 reguser@wangdenghui
    --table 要向链上查询的TABLE名 (参考ABI文件TABLE描述)
    --key 要向链上查询的key关键字的值,是关键字的值

    bcli gettable --contract reguser@wangdenghui --table userinfo --key duncan

    【成功结果】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli gettable --contract reguser@wangdenghui --table userinfo --key duncan
    {
        "contract": "reguser@wangdenghui",
        "object": "userinfo",
        "key": "duncan",
        "value": "dc0001da0007476f6f644d616e"
    }
    
    Table data is :map[userinfo:GoodMan]
    
    【错误执行结果】-部署参数错误
    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli gettable --contract register@wangdenghui --table userreginfo --key userName
    BCliGetTableInfo error:
        errcode:10205 msg:"query object: object not found" 
    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli gettable --contract register@wangdenghui --table userinfo --key userreginfo
    BCliGetTableInfo error:
        errcode:10205 msg:"query object: object not found" 
    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli gettable --contract register@wangdenghui --table userreginfo --key duncanwang
    BCliGetTableInfo error:
        errcode:10205 msg:"query object: object not found" 
    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli gettable --contract register@wangdenghui --table userreginfo --key userinfo.userName
    BCliGetTableInfo error:
        errcode:10205 msg:"query object: object not found" 
    

    【原因分析】
    if (!saveData(userBaseInfo, tablename, userinfo.userName)) return ERROR_SAVE_DB_FAIL;
    table的名为testRegUser.abi字"userinfo",查找关键字为:"table_name": "userinfo";key的内容为第3个参数的实际值,就是下面命令的userName:duncan值。

    bcli transaction push --sender wangdenghui --method reguser --contract reguser@wangdenghui --param "userName:duncan, userInfo:GoodMan"

    2.3 NVN和NPM安装

    (1)安装NVM
    NVM(Node Version Manager,Node多版本管理器),是一个可以让你在同一台机器上安装和切换不同版本node的工具。

    curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

    【成功结果】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/contact$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100 12819  100 12819    0     0   1976      0  0:00:06  0:00:06 --:--:--  3235
    => Downloading nvm from git to '/home/duncanwang/.nvm'
    => Cloning into '/home/duncanwang/.nvm'...
    remote: Enumerating objects: 267, done.
    remote: Counting objects: 100% (267/267), done.
    remote: Compressing objects: 100% (242/242), done.
    remote: Total 267 (delta 31), reused 86 (delta 15), pack-reused 0
    Receiving objects: 100% (267/267), 119.47 KiB | 236.00 KiB/s, done.
    Resolving deltas: 100% (31/31), done.
    => Compressing and cleaning up git repository
    
    => Appending nvm source string to /home/duncanwang/.bashrc
    => Appending bash_completion source string to /home/duncanwang/.bashrc
    => Close and reopen your terminal to start using nvm or run the following to use it now:
    
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
    [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
    

    (2)重启系统或者重新读入初始化文件
    source:使当前shell读入路径为filepath的shell文件并依次执行文件中的所有语句,通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。

    source ~/.bashrc

    (3)nvm install安装NODE.JS版本
    nvm ls-remote可查看node所有版本,然后选择安装

    【执行结果】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/contact$ nvm install 8.15.0
    Downloading and installing node v8.15.0...
    Downloading https://nodejs.org/dist/v8.15.0/node-v8.15.0-linux-x64.tar.xz...
    ######################################################################################################################################################################################## 100.0%
    Computing checksum with sha256sum
    Checksums matched!
    Now using node v8.15.0 (npm v6.4.1)
    Creating default alias: default -> 8.15.0 (-> v8.15.0)
    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/contact$ node -v
    v8.15.0
    

    (4)安装bottos-sdk-js

    npm install bottos-sdk-js --save
    【成功执行结果】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/contact$ npm install bottos-sdk-js --save
    
    > secp256k1@2.0.4 install /home/duncanwang/go/work/contract-tool-cpp/contact/node_modules/eccrypto/node_modules/secp256k1
    > npm run rebuild
    
    
    > secp256k1@2.0.4 rebuild /home/duncanwang/go/work/contract-tool-cpp/contact/node_modules/eccrypto/node_modules/secp256k1
    > node-gyp rebuild
    ...
    make: Leaving directory '/home/duncanwang/go/work/contract-tool-cpp/contact/node_modules/secp256k1/build'
    
    > protobufjs@6.8.8 postinstall /home/duncanwang/go/work/contract-tool-cpp/contact/node_modules/protobufjs
    > node scripts/postinstall
    
    npm WARN saveError ENOENT: no such file or directory, open '/home/duncanwang/go/work/contract-tool-cpp/contact/package.json'
    npm notice created a lockfile as package-lock.json. You should commit this file.
    npm WARN enoent ENOENT: no such file or directory, open '/home/duncanwang/go/work/contract-tool-cpp/contact/package.json'
    npm WARN contact No description
    npm WARN contact No repository field.
    npm WARN contact No README data
    npm WARN contact No license field.
    
    + bottos-sdk-js@0.5.0
    added 58 packages from 74 contributors and audited 185 packages in 82.779s
    found 0 vulnerabilities
    

    (5)安装并启动 lite-server
    【定义】lite-server 是轻量级的,仅适用于开发 的 node 服务器, 它仅支持 web app。 它能够为你打开浏览器, 当你的html或是JavaScript文件变化时,它会识别到并自动帮你刷新浏览器, 还能使用套接字自动注入变化的CSS, 当路由没有被找到时,它将自动后退页面。
    1)安装lite-server

    npm install lite-server --save-dev
    【结果】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ npm install lite-server --save-dev
    npm WARN testRegUser@1.0.0 No repository field.
    npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules/fsevents):
    npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
    
    + lite-server@2.4.0
    added 345 packages from 274 contributors, removed 55 packages and audited 2607 packages in 31.781s
    found 0 vulnerabilities
    

    2)启动lite-server

    npm run dev

    【结果】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ npm run dev
    
    > testRegUser@1.0.0 dev /home/duncanwang/go/work/contract-tool-cpp/testRegUser
    > lite-server
    
    Did not detect a `bs-config.json` or `bs-config.js` override file. Using lite-server defaults...
    ** browser-sync config **
    { injectChanges: false,
      files: [ './**/*.{html,htm,css,js}' ],
      watchOptions: { ignored: 'node_modules' },
      server: { baseDir: './', middleware: [ [Function], [Function] ] } }
    [Browsersync] Access URLs:
     -------------------------------------
           Local: http://localhost:3000
        External: http://10.225.18.68:3000
     -------------------------------------
              UI: http://localhost:3001
     UI External: http://localhost:3001
     -------------------------------------
    [Browsersync] Serving files from: ./
    [Browsersync] Watching files...
    [Browsersync] Couldn't open browser (if you are using BrowserSync in a headless environment, you might want to set the open option to false)
    

    2.4 DAPP界面操作

    (1) 本地windows上运行网页

    本地windwos的chrome浏览器上运行网页,例如虚拟机 服务器地址:http://10.225.18.68:3000/

    (2)点击 查询合约 结果按钮

    查询合约不需要账户信息,只要输入http网址即可查询到合约内容。
    查看可知同CLI命令查询的结果。

    {"errcode":0,"msg":"success","result":{"contract":"reguser@wangdenghui","object":"userinfo","key":"duncan","value":"dc0001da0007476f6f644d616e"}}
    

    截图:


    3.查询合约结果.png

    (3)点击 运行合约

    输出结果:

    {"errcode":0,"msg":"success","result":{"trx":{"version":65536,"cursor_num":7934,"cursor_label":773838136,"lifetime":1548324372,"sender":"wangdenghui","contract":"reguser@wangdenghui","method":"reguser","param":"dc0002da000764756e63616e32da000847726561744d616e","sig_alg":1,"signature":"666e849512b77ef2c46daca204ad6e51b23ecd78698e75ffa3d65afeb3f24ea16a6b533a2ab38e4dae46bb853a6a3d458aabe7776d5134cbc7a055a06b6c4de3"},"trx_hash":"b56eaf25b2ac1ff81e547f8efb87d5ef1423afec1dbdd9a8af75ad4e2dd0de61"}}
    

    在命令行下查询结果,发现该交易执行是成功的。

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ bcli transaction get --trxhash  b56eaf25b2ac1ff81e547f8efb87d5ef1423afec1dbdd9a8af75ad4e2dd0de61
    {
        "ResourceReceipt": {
            "account_name": "wangdenghui",
            "space_token_cost": 190,
            "time_token_cost": 376
        },
        "Transaction": {
            "contract": "reguser@wangdenghui",
            "cursor_label": 773838136,
            "cursor_num": 7934,
            "lifetime": 1548324372,
            "method": "reguser",
            "param": {
                "userinfo": "GreatMan",
                "username": "duncan2"
            },
            "sender": "wangdenghui",
            "sig_alg": 1,
            "signature": "666e849512b77ef2c46daca204ad6e51b23ecd78698e75ffa3d65afeb3f24ea16a6b533a2ab38e4dae46bb853a6a3d458aabe7776d5134cbc7a055a06b6c4de3",
            "version": 65536
        },
        "TrxHash": "b56eaf25b2ac1ff81e547f8efb87d5ef1423afec1dbdd9a8af75ad4e2dd0de61"
    }
    
    <<<Transaction Status>>> : commited
    

    【说明】目前BOTTOS智能合约还不支持复杂结构体的数据存链动作。

    (8) BOTTOS创建账户

    目前机制下,BOTTOS账户创建成功后,如果要用于部署合约,还需要质押一定的TOKEN。所以只演示创建账号而已。

    创建账户执行结果-成功

    {"errcode":0,"msg":"success","result":{"trx":{"version":65536,"cursor_num":5873,"cursor_label":1210352703,"lifetime":1548318177,"sender":"wangdenghui","contract":"bottos","method":"newaccount","param":"dc0002da000b746573746163636f756e74da008230346636373733333833363437636236613461393162663134396462656430393935633931376533323637336435313132393331613466663538663335343630663838313137366665383065373933663533363037613736643034643764393638323965376562643061626530656139646331363061313366343435366461656131","sig_alg":1,"signature":"176c4b0e86073050201a7da745ba95c193ac694b29145c5be46abcc43f9cc8861b7f99005b103624457acd597059618f909db158b59ba2042d9e3b7291b5739a"},"trx_hash":"760b5c19fc716ce980d9a6180e82e1942e237b8eb76a70e8925fefb452530ca9"}}
    

    截图:


    2.运行合约.png

    命令行查看,可以看到该账号。该账号可以跟创建的钱包关联起来,也可以不用关联起来,它会一直存在网上。

    ./bcli account get --account testaccount

    duncanwang@ubuntu64bit-server:~/go/src/github.com/bottos$  ./bcli account get --account testaccount
    
       Account: testaccount
       Balance: 0.00000000 BTO
       Pubkey: 04f6773383647cb6a4a91bf149dbed0995c917e32673d5112931a4ff58f35460f881176fe80e793f53607a76d04d7d96829e7ebd0abe0ea9dc160a13f4456daea1
    
       StakedBalance: 0.00000000 BTO
       UnStakingBalance: 0.00000000 BTO
       StakedSpaceBalance: 0.00000000 BTO
       StakedTimeBalance: 0.00000000 BTO
       UnStakingTimestamp: 0
    
       AvailableSpaceBalance: 0
       UsedSpaceBalance: 0
       AvailableTimeBalance: 0
       UsedTimeBalance: 0
    
       UnClaimedReward: 0.00000000 BTO
    
       Vote: N/A
    
       Contracts: N/A
    
    常见错误-端口链接拒绝

    【错误提示】
    输入网址http://192.168.1.105:3000/链接主页,采用chrome的检查模式,发现以下错误:

    http://192.168.1.108:8689/v1/block/height net::ERR_CONNECTION_REFUSED

    【分析】

    duncanwang@ubuntu64bit-server:~/go/work/contract-tool-cpp/testRegUser$ netstat -nltp
    (Not all processes could be identified, non-owned process info
     will not be shown, you would have to be root to see it all.)
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 127.0.0.1:8689          0.0.0.0:*               LISTEN      22034/./bottos      
    tcp        0      0 127.0.0.1:6869          0.0.0.0:*               LISTEN      22034/./bottos      
    tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -                   
    tcp        0      0 127.0.0.1:6870          0.0.0.0:*               LISTEN      22034/./bottos      
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
    tcp6       0      0 :::9868                 :::*                    LISTEN      22034/./bottos      
    tcp6       0      0 :::22                   :::*                    LISTEN      -                   
    tcp6       0      0 :::3000                 :::*                    LISTEN      23004/lite-server   
    tcp6       0      0 :::3001                 :::*                    LISTEN      23004/lite-server
    

    以上代码表示8689只能被127.0.0.1调用。修改 config.toml,把localhost改为0.0.0.0,就不会有这个错误了。

    [Rest]
    RESTPort = 8689
    RESTHost = "0.0.0.0"
    
    [Plugin.Wallet]
    WalletDir = ""
    WalletRESTPort = 6869
    WalletRESTHost = "0.0.0.0"
    

    3,参考

    1)使用C++编写智能合约
    2)DApp开发与调试(JavaScript版本)
    3)API Document
    4)bottos-sdk-js API Document
    5) linux查看和修改PATH环境变量的方法

    相关文章

      网友评论

        本文标题:铂链第5课 如何在BOTTOS上搭建第一个DAPP应用[C++程

        本文链接:https://www.haomeiwen.com/subject/nxrujqtx.html