《智能合约开发课》学习7:代投后发给多个参投方
根据最近学习的内容,我编了一个应用场景:
几个人合伙凑出几个ETH,发给代投方agent;代投方发放token后,按份额发给每个参与者
1)结构struct
这个需求里涉及了多个参与者,我们需要记录其钱包地址和参投的份额。Solidity支持struct结构类型,这点与C语言非常相似,建立一个参与者的结构后,可以记录每个参与者的地址和参投数量。
struct Participator {
address addr;
uint amount;
}
2)数组
Solidity支持定长数组和动态数组,这里我们的参投人数是不定的,所以用动态数组。
Participator []participators;
在动态数组中增加一个元素用push()函数。参投者向合约地址里支付ETH后,需要记录其地址和参加的份额。这里需要在addFund()函数中增加这样一行。
participators.push(Participator(msg.sender, msg.value));
3)安全考虑
涉及到转账操作时要特别注意,不能让无关人员执行这些函数,通常的做法是声明一个成员变量address owner,然后在构造函数中记录合约的创建者owner。
构造函数的名称与合约名称一致,并且不带任何参数。
function CoinProxy() {
owner = msg.sender;
}
然后在各个函数中判断函数的调用者是否有权限执行转账操作,如果没有权限,中止函数的执行。
if(msg.sender != owner) {
revert();
}
4)异常处理及状态回滚
solidity在执行过程中如果遇到异常要保持原子操作的完整性,需要将各种状态恢复成调用前的状态,需要用到revert()函数。在比较早的solidity版本中都用throw(),现在统统用revert()。
在solidity中经常要进行这些类似的判断,如果都用if语句,则显得非常臃肿,可以把上面的if语句用require写成一行。
require(msg.sender == owner);
这种表达方式在solidity中大量存在,语法精练,语义清晰。
5)统计参投的总币数
for语法与C语言一样,没什么可讲的。
uint total = 0;
for(uint i = 0; i<participators.length; i++){
total += participators[i].amount;
}
6)发出token
收到代投方换回的token后,要发给每个参投方。这里我还不知道如何发放ERC-20代币,先假设发放balance里的ether吧。这里按份额发放即可。
for(i = 0; i<participators.length; i++){
participators[i].addr.transfer(this.balance * participators[i].amount / totalEthers);
}
主要的步骤就是这些,程序里还有一些问题没有考虑,没有考虑代投过程的起止时间,如果换回token后,仍有人追加资金,份额的计算是有问题的。这些细节留着以后再考虑。
完整的代码:
pragma solidity ^0.4.14;
contract CoinAgent {
// 与C语言类似,支持结构类型
struct Participator {
address addr;
uint amount;
}
//用remix中生成的第5个测试地址,收集到的ETH发给他
address agent = 0xdd870fa1b7c4700f2bd7f44238821c26f7392148;
// 参投方,动态数组
Participator []participators;
address owner;
function CoinAgent() {
owner = msg.sender;
}
// 每个参投方调用这个函数参投
function addFund() payable returns(uint) {
participators.push(Participator(msg.sender, msg.value));
return this.balance;
}
// 送给代投方
function sendToAgent() {
if(msg.sender != owner) {
revert();
}
agent.transfer(this.balance);
}
// 把tokens按照参加份额发给每个参投人
// 当前还不知道如何发ERC-20代币,先发ETH
function sendTokens() {
require(msg.sender == owner);
uint total = 0;
for(uint i = 0; i<participators.length; i++){
total += participators[i].amount;
}
// 前面定义的i变量在整个函数中都可以访问
for(i = 0; i<participators.length; i++){
participators[i].addr.transfer(this.balance * participators[i].amount / total);
}
}
}
本文由币乎(bihu.com)内容支持计划奖励
Leave 《智能合约开发课》学习7:代投后发给多个参投方 to:
Read more #cn posts
Best Posts From 申龙斌
We have not curated any of speeding's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.