900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 基于mcat开发智能合约应用(二)调用合约

基于mcat开发智能合约应用(二)调用合约

时间:2019-11-20 10:35:34

相关推荐

基于mcat开发智能合约应用(二)调用合约

#### 准备工作

上一节中已经演示了如何通过`mcat`编译和部署合约,此处演示下怎么使用`mcat`来与合约进行交互。

部署合约后得到合约账户地址 `0xd2548bb40fe57aa9e66aeafbc1f6a44c9d8b9532`。 [合约](/luren5/84e531e75392765efbb7fde250d6c315)的内容比较简单,功能如下:

1、投票发起人可以给其它账户地址进行授权 `giveRightToVote()`

2、被授权的账户可以进行投票 `vote()`

3、最后可以实时查询投票最多的候选项的编号 `winningProposalIndex()` 和名字 `winnerName()`

根据前一节演示可以看到,部署合约的时候初始化了两个候选项`Hillary` 、`Trump` 编号依次是0 和1

#### 授权

授权操作只能是合约创建者来完成(当然这不是固定的,只是此处合约逻辑规定如此),所以此时还是使用`mcat.yaml`里面配置的那个账户来发起这笔交易。我这里有三个账户,第一个账户是合约的创建者,用它来给后两个账户授权

```

> personal.listAccounts

["0x0b9498ca74cd7814fba0c25e2a441c1d5867946a", "0xb01a8b45f7e01651eda132dbd6fb985a7022f171", "0x15cab6f047549b6ed7392feb5c217d3893a6acb6"]

```

可以看到`giveRightToVote(address voter, bytes32 voterName) `方法有两个参数,第一个是被授权账户的地址,第二个是投票人的名字

```

mcat call --addr="0xd2548bb40fe57aa9e66aeafbc1f6a44c9d8b9532" --contract="Ballot" --function="giveRightToVote" --params="0xb01a8b45f7e01651eda132dbd6fb985a7022f171&voter1"

```

调用成功并返回了这笔合约交易的`hash`, 开启挖矿让这笔交易被打包。 然后来验证下授权是否成功。

#### 验证授权是否成功

合约的状态变量`mapping(address => Voter) public voters;` 是用来记录所有已经被授权的地址的。由于它是`public`类型的合约状态变量,所以编译的时候会自动生成对应的`getter`方法`voters(addr)` (在abi里面可以看到),由于它只是读取数据不需要修改账本,所以它是`constant`类型的,此处调用`callConst`来查询

```

mcat callConst --addr="0xd2548bb40fe57aa9e66aeafbc1f6a44c9d8b9532" --contract="Ballot" --function="voters" --params="0xb01a8b45f7e01651eda132dbd6fb985a7022f171"

0xa3ec138d000000000000000000000000b01a8b45f7e01651eda132dbd6fb985a7022f171

0x766f746572310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059b025e90000000000000000000000000000000000000000000000000000000000000000

```

`callConst` 和 `call` 用法类似,但是前者调的是`eth_call`接口,它只会查询区块链上的数据并即时返回结果,而后者是调用`eth_sendTransaction`接口,它会发起一笔交易(即使有constant关键字)并返回这笔交易的hash。

从返回的结果可以看出,它是一串经过编码的后的字节码,里面包含了`0xb01a8b45f7e01651eda132dbd6fb985a7022f171`voter的相关属性值, 关于怎么解码mcat正在开发在,将在下一个版本中发布。

由上可以看出,确实已经授权成功。如法炮制,给第三个地址授权

```

mcat call --addr="0xd2548bb40fe57aa9e66aeafbc1f6a44c9d8b9532" --contract="Ballot" --function="giveRightToVote" --params="0x15cab6f047549b6ed7392feb5c217d3893a6acb6&voter2"

```

#### 投票

现在我们用第二个地址,来给选项1(从0开始计数) `Trump`投一票

因为这里是用地址二`0xb01a8b45f7e01651eda132dbd6fb985a7022f171`来投票,也就是从这个地址发起一笔交易,所以我们需要修改下 `mcat.yaml`, 把development模式里面的账户地址和密码改成地址二的信息,然后执行`mcat loadConfig`重新加载一下配置

```

```

注意:真实情况下, 投票发起人(地址一)和被授权地址不会在一个节点,也不会是由同一个人掌握(否则自己给自己授权,然后自己再来投票,没有任何意义)。这里由于是演示,所以发起人和被授权地址在同一个节点里,所以需要改下mcat.yaml里面的配置,真实情况它们(授权 和 投票)应该分属于两个应用

```

// mcat.yaml

account: "0xb01a8b45f7e01651eda132dbd6fb985a7022f171"

password: "123456"

// 重新加载

mcat loadConfig

Succeed in loading mcat config.

```

开始投票

```

mcat call --addr="0xd2548bb40fe57aa9e66aeafbc1f6a44c9d8b9532" --contract="Ballot" --function="vote" --params="1"

```

等待打包

#### 查看投票结果

走完以上步骤后,地址`0xb01a8b45f7e01651eda132dbd6fb985a7022f171`给选项1`Trump`投了一票,而选项0还没有被投票,那么此时winnerIndex应该是0,winnerName应该是Trump,来验证一下

```

mcat callConst --addr="0xd2548bb40fe57aa9e66aeafbc1f6a44c9d8b9532" --contract="Ballot" --function="winningProposalIndex"

0x8ec36a3d

0x0000000000000000000000000000000000000000000000000000000000000001

mcat callConst --addr="0xd2548bb40fe57aa9e66aeafbc1f6a44c9d8b9532" --contract="Ballot" --function="winnerName"

0xe2ba53f0

0x5472756d70000000000000000000000000000000000000000000000000000000

```

结果如预期!

#### 小结

以上是纯手工调用mcat的命令来完成一个合约的调用过程,这适用于上线前的 调试,生产环境肯定是需要通过编码来自动化完成这些操作的,mcat也提供了相应的功能来满足需求,将在下一节中演示!

原文地址:/p/29123951

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。