Toc
  1. 开发前准备
    1. 安装SDK
    2. 准备SSL证书文件
    3. 创建账户
    4. 获取链节点 IP 和端口号
  2. 创建与初始化SDK实例
  3. 部署智能合约
    1. 下载并安装 solc-js合约编译工具
    2. 读取并编译合约,并创建合约实例
    3. 部署合约
  4. 调用智能合约
  5. 更新智能合约
  6. 总结
Toc
0 results found
FT-JOHN
阿里云BaaS下蚂蚁区块链开发实践(二)

21antblockchain

本文将继续介绍我在阿里云下基于蚂蚁区块链开发的产品溯源Demo客户端部分。蚂蚁链提供了两个平台的客户端SDK:Java与Node.js,我使用的是JS SDK。

开发前准备

安装SDK

  • node.js官网下载并安装 Node.js(推荐使用 v10.11.0 及以上版本)。
  • 到链管理页面下载蚂蚁链SDK,下载的压缩包中同时包含JAVA与JS SDK。
    下载SDK
  • 将JS SDK alipay-mychain-0.2.27.tgz,并安装在项目目录
    npm i alipay-mychain-0.2.27.tgz --save

    准备SSL证书文件

    客户端与区块链节点之间的通讯使用SSL双向加密,以保证不被中途拦截与篡改。客户端访问需要三个证书:
  • client.key 管理员线下自行生成或在创建节点时由baas自动生成(由于服务器不保存客户端私钥,此文件只允许下载一次)
  • client.crt 节点创建成功后,可在bass平台中的链管理界面下载
  • ca.crt 节点创建成功后,可在bass平台中的链管理界面下载
    这三个证书文件要放在客户端项目目录,以备用。

    创建账户

    蚂蚁链通过“账户”来管理客户端的访问权限,在启动开发前,需要在蚂蚁链BaaS平台的“成员管理”中,添加相应的账户。
    成员管理
    添加账户需要提交账户公钥,账户公私角可由线下生成进行提交,也可以由线上生成(由于服务器不保存账户私钥,此账户的密钥文件只允许下载一次)
    创建账户
    账户创建好后,要保存将账户私钥key文件,并将使用openssl将其转成pem格式:
    openssl ec -in user.key -passin pass:${key_password} -passout pass:${key_password} -aes256 -out user.pem

获取链节点 IP 和端口号

要与合约链交互,您需要获取链节点的 IP 地址和端口号。在 BaaS 平台,通过查看目标合约链详情,在区块浏览器中查看节点详情,可获取链节点的 IP 地址和端口号。

创建与初始化SDK实例

  1. 引入JS SDK
    const Chain = require("./build/index.node")
  2. 配置环境参数
    const fs = require("fs")
    const currentUserName = 'john' //当前账户名
    const userPemFolder = 'john'; //当前账户pem文件所在目录
    const accountPassword = "Abcd@1234" //pem文件密码
    const passphrase = "Abcd@1234" // SSL证书文件密码

    let accountKey = fs.readFileSync("./certs/" + userPemFolder + "/user.pem",{encoding: "utf8"})
    let keyInfo = Chain.utils.getKeyInfo(accountKey, accountPassword)

    let opt = {
    host: '127.0.0.1', //目标区块链网络节点的 IP
    port: 18130, //端口号
    timeout: 30000, //连接超时时间配置
    cert: fs.readFileSync('./certs/client.crt', {encoding: 'utf8'}), //读取RSA密钥
    ca: fs.readFileSync('./certs/ca.crt', {encoding: 'utf8'}), //读取CA证书
    key: fs.readFileSync("./certs/client.key", {encoding: "utf8"}), //读取RSA证书
    userPublicKey: keyInfo.publicKey,
    userPrivateKey: keyInfo.privateKey,
    userRecoverPublicKey: keyInfo.publicKey,
    userRecoverPrivateKey: keyInfo.privateKey,
    passphrase: passphrase
    }
  3. 初始化一个连接实例
    let chain = Chain(opt)

    部署智能合约

    下载并安装 solc-js合约编译工具

    由于蚂蚁区块链对 Solidity 语言的支持与原生的 Solidity 语言不同,因此不能使用外部社区的 solc-js 编译工具。只能使用BaaS 平台提供的 solc-js:alipay-solc-0.1.10.tgz 可兼容 Solidity 语言 0.4.24 版本之前的语法(不包含 0.4.24)。
  4. 下载 solc-js
    点击此处,获取合约编译工具 solc-js 安装包:alipay-solc-0.1.10.tgz
  5. 全局安装 solc-js
    全局安装 solc-js。在下载的 alipay-solc-0.1.10.tgz 所在目录执行以下命令:
    npm i -g alipay-solc-0.1.10.tgz
    安装完成后,可以在命令行中使用solc-js 来编译合约,命令参数与原生程序基本一致。
  6. 如果需要在代码中动态编译合约,则需要按下面步骤进行安装:
    a. 在项目目录下npm init,将 alipay-solc-0.1.10.tgz 文件放到 项目目录
    b. 运行以下命令行,在项目目录中安装 solc-js:
    npm i alipay-solc-0.1.12.tgz --save
     c. 在代码中引用solc-js:
    let solc = require('@alipay/solc')

    读取并编译合约,并创建合约实例

    const contractName = 'contractTKManager'
    let contract = fs.readFileSync('./TKManager.sol', {encoding: 'ascii'})
    // 第二个参数设定为"1",会开启编译优化 optimiser
    let output = solc.compile(contract, 1)
    let abi = JSON.parse(output.contracts[':TKManager'].interface)
    let bytecode = output.contracts[':TKManager'].bytecode
    let myContract = chain.ctr.contract(contractName, abi)

    部署合约

    myContract.new(bytecode, {
    from: currentUserName,
    }, (err, contract, data) => {
    console.log(data)
    let original_block_number = data.block_number //这个是合约上链所在的区块号,需记录下来,更新合约时会用到
    console.log('original_block_number:', original_block_number)
    })

    调用智能合约

    蚂蚁链是通过合约名来访问智能合约的,不需要记住合约地址,这样也方便了合约的更新。因此合约一旦部署后,只需要提供合约名以及abi对象,就可以开始调用智能合约了。
    //初始化一个连接实例
    let chain = Chain(opt)
    let solc = require('@alipay/solc')

    let contract = fs.readFileSync('./TKManager.sol', {encoding: 'ascii'})
    // 第二个参数设定为"1",会开启编译优化 optimiser
    let output = solc.compile(contract, 1)
    let abi = JSON.parse(output.contracts[':TKManager'].interface)
    let bytecode = output.contracts[':TKManager'].bytecode
    let myContract = chain.ctr.contract(contractName, abi)

    myContract.AddProduct(productName, modelName, description, {from: currentUserName}, (err, output, data) => {
    //判断合约调用是否出错
    if(typeof(err) != 'undefined') {
    console.log('err is:', err)
    } else {
    //调用成功,合约方法返回值可以通过 output参数获取到
    console.log('output is:', output.toString())
    }
    process.exit(0)
    })

    更新智能合约

    蚂蚁链的合约升级更新稍有点复杂,主要的部署是:
  7. 先将合约在本地执行模拟部署(new),模拟部署的block_number参数应设置为合约第一次发布时所在的区块号减1,也就是发布合约时获得的参数 original_block_number - 1
  8. 本地部署完成后,会返回“runtime”字节码(bytecode)
  9. 将获得的字节码更新到链上(update)
    //合约第一次上链的区块号
    let original_block_number = 570177
    myContract.new(bytecode, {
    from: currentUserName,
    local: true, //本地执行合约部署,目的为了模拟合约部署获取`runtime`字节码
    block_number: original_block_number - 1, //防止合约id冲突
    }, (err, contract, data) => {
    myContract.update(
    //这里注意要做替换
    data.receipt.output.replace('0x' + chain.EVM, ''),
    {}, (err, contract, data) => {
    console.log("solidity contract has been updated")
    process.exit(0)
    })
    })
    })

    总结

    至此,从创建区块链网络、节点与账户,到开发智能合约,到在客户端中实现合约部署、升级以及调用,蚂蚁区块链的主要开发流程就已经介绍完了。对于蚂蚁链我的感受是,因为它与阿里云深度结合,不管是从部署、运维到合约开发、调试都是非常方便,可以节省大量的时间与成本让用户更多地关注在业务实现上。感觉不太方便的地方是支持的solidity版本太旧,智能合约的更新有点复杂不太好理解,希望能看到它持续进步。

完整Demo代码请参考:https://github.com/ft-john/antblockchain_demo

本文作者:FT-JOHN
版权声明:本文首发于FT-JOHN的博客,转载请注明出处!