我爱编程星云链DApp开发step by step

三、创建合约

2018-05-16  本文已影响0人  sxplus

上一节我们创建了钱包,并领取了免费的NAS,现在我们来到DApp化的核心步骤——创建合约。

编写合约

星云链的合约需要用javascript或Typescript编写,一个合约定义了一个javascript对象的构造函数,构造函数里定义了对象所具有的方法。

对于应用开发者,每一个方法就是一个和星云链交互的接口,合约要定义什么样的方法是由应用的需求决定的,也就在在第一节一、一个普通App里面提到的,设计应用之初,应该考虑需要在星云链存储或者获取什么数据。

智能合约例子

这里我们用一个例子来看一个合约包括哪些智能合约-SmartContract

"use strict";

var DepositeContent = function (text) {
    if (text) {
        var o = JSON.parse(text);
        this.balance = new BigNumber(o.balance);
        this.expiryHeight = new BigNumber(o.expiryHeight);
    } else {
        this.balance = new BigNumber(0);
        this.expiryHeight = new BigNumber(0);
    }
};

DepositeContent.prototype = {
    toString: function () {
        return JSON.stringify(this);
    }
};

var BankVaultContract = function () {
    LocalContractStorage.defineMapProperty(this, "bankVault", {
        parse: function (text) {
            return new DepositeContent(text);
        },
        stringify: function (o) {
            return o.toString();
        }
    });
};

// save value to contract, only after height of block, users can takeout
BankVaultContract.prototype = {
    init: function () {
        //TODO:
    },

    save: function (height) {
        var from = Blockchain.transaction.from;
        var value = Blockchain.transaction.value;
        var bk_height = new BigNumber(Blockchain.block.height);

        var orig_deposit = this.bankVault.get(from);
        if (orig_deposit) {
            value = value.plus(orig_deposit.balance);
        }

        var deposit = new DepositeContent();
        deposit.balance = value;
        deposit.expiryHeight = bk_height.plus(height);

        this.bankVault.put(from, deposit);
    },

    takeout: function (value) {
        var from = Blockchain.transaction.from;
        var bk_height = new BigNumber(Blockchain.block.height);
        var amount = new BigNumber(value);

        var deposit = this.bankVault.get(from);
        if (!deposit) {
            throw new Error("No deposit before.");
        }

        if (bk_height.lt(deposit.expiryHeight)) {
            throw new Error("Can not takeout before expiryHeight.");
        }

        if (amount.gt(deposit.balance)) {
            throw new Error("Insufficient balance.");
        }

        var result = Blockchain.transfer(from, amount);
        if (!result) {
            throw new Error("transfer failed.");
        }
        Event.Trigger("BankVault", {
            Transfer: {
                from: Blockchain.transaction.to,
                to: from,
                value: amount.toString()
            }
        });

        deposit.balance = deposit.balance.sub(amount);
        this.bankVault.put(from, deposit);
    },

    balanceOf: function () {
        var from = Blockchain.transaction.from;
        return this.bankVault.get(from);
    },

    verifyAddress: function (address) {
        // 1-valid, 0-invalid
        var result = Blockchain.verifyAddress(address);
        return {
            valid: result == 0 ? false : true
        };
    }
};

module.exports = BankVaultContract;

这份智能合约定义了5个接口。
init接口是一个合约必须要有的方法。
save, takeout, balanceOf, verifyAddress 分别是存钱,转账,查询合约余额,校验合约地址。

星云链库简介

合约中用到星云链提供的一些库:

Blockchain 有两个属性:
1、block 执行合约的当前区块,它具有下列属性:
— timestamp 区块时间戳
— height 区块高度
2、transaction 执行合约的当前交易,它具有下列属性:
— hash 交易哈希值
— from 交易源地址
— to 交易目的地址,对于合约调用就是合约地址
— value 交易数值,字符串, 合约内用BigNumber存储计算
— nonce 交易的 nonce 值
— timestamp 交易时间戳
— gasPrice 交易的 gasPrice,字符串,合约内用 BigNumber 存储计算
— gasLimit 交易的 gasLimit,字符串,合约内用 BigNumber 存储计算

Blockchain 还提供了两个方法:
1、transfer(address, value) 将 NAS 从合约转出到address对应的账户。
· 参数 address:接收 NAS 的 Nebulas 账户地址
· 参数 value:转移数值,一个 BigNumber 对象
返回:0 – 转移成功,1 – 转移失败

2、verifyAddress(address) 验证参数 address 是否为一个有效的 Nebulas 地址。
返回:1 – 地址有效,0 – 地址无效


请参照智能合约的例子编写自己的合约。

部署合约

编写完自己的合约,就可以部署到星云链上来调用了。
打开二、创建钱包里下载的星云钱包的主页web-wallet/index.html,打开Contract页,选择Deploy页面

合约3-1

code里面粘贴整个合约的源代码,语言选择Javascript,arguments留白,选择钱包keystore文件并输入钱包密码,点击unlock解锁钱包信息。
From AddressTo Address都自动填充为钱包地址,Balance显示的是钱包余额,点击Test

合约3-2

显示这样的结果表示合约没有问题,点击Submit就正式部署合约。

合约3-3

txhash是合约哈希,contract_address是合约地址,保存好这两个值。

此时合约部署成功。

调用合约

点击Call来到合约调用页面,此页面供开发者测试合约中的方法,建议在应用中调用合约之前都在此先测试合约方法。

function: 要调用的合约的方法,如智能合约中的 save, takeout, balanceOf。
arguments: 调用的方法的参数,如智能合约中save方法,需要参数[‘1000’],如果方法不需要参数,则不填写。
From Address: 钱包地址
To Address: 合约地址,此处需要注意

下面测试智能合约中的balanceOf方法


合约3-4

点击Test,返回结果中result为null,对于新创建的合约,还没有在合约地址中存入任何数据,所以查询到的结果为null。

我们尝试先调用save存入数据。
Value/Amount to Send这里的单位是NAS, 所以对于NAS不多的同学来说,这里一定要填小一点的数比如0.000000000000000001或者直接0(如果你的交易数据不是Value/Amount的话),开源节流嘛,如果你的Value/Amount大于你的钱包余额,调用会出现NAS不足的错误。

先单击Test测试合约调用是否正常

合约3-5

以上结果说明合约调用正常,再点击Submit提交交易,数据才会真正的存储到星云链。每个交易会返回txhash, 可以在Check TX Status查看交易的状态,只有状态为Success,交易才被存储到了链上。

然后我们再次调用banlanceOf接口,可以看到我们调用save接口存储在星云链上的数据。


合约3-6

合约部署并测试成功了,就可以将我们的应用DApp化了四、DApp化

如果你觉得本教程对你有用,请使用本邀请链接注册星云链星云链注册入口,谢谢!

上一篇 下一篇

猜你喜欢

热点阅读