这两天 EOS 众筹正火,蹭个热点,技术面分析下 EOS的众筹合约
项目地址
https://github.com/EOSIO/eos-token-distribution
项目目录
├── Dappfile // dapphub 出品的智能合约开发工具
├── Makefile
├── bin
│ └── deploy // 部署脚本
├── lib // 第三方依赖
│ ├── ds-auth // 权限控制
│ ├── ds-exec
│ ├── ds-guard
│ ├── ds-math // 数学运算
│ ├── ds-test // 测试框架
│ ├── ds-token // Token 框架
│ └── gnosis-multisig
└── src // 源码
├── eos.sol
└── eos.t.sol
本项目使用 Dapphub 出品的智能合约开发框架 dapp 开发。Dapphub 开源了很多实用的库,大大简化了智能合约的开发成本。
代码分析
变量
DSToken public EOS; // EOS Token
uint128 public totalSupply; // Token 总量
uint128 public foundersAllocation; // 开发团队保留份额
string public foundersKey; // 保留份额 Holder Address
uint public openTime; // window 0 开始时间
uint public createFirstDay; // window 0 供应量
uint public startTime; // window 1 开始时间
uint public numberOfDays; // window 总数
uint public createPerDay; // 每日供应量
EOS 的 ICO 规则为:前五天为一个 window 总共发行 2 亿 Token。五天之后,每23个小时为一个window,发行 2 百万 Token。总共发行 10 亿 Token。
构造函数
// src/eos.sol
function EOSSale(
uint _numberOfDays,
uint128 _totalSupply,
uint _openTime,
uint _startTime,
uint128 _foundersAllocation,
string _foundersKey
) {
...
// window 0 Token 供应量
createFirstDay = wmul(totalSupply, 0.2 ether);
// window 1 以及以后的每天 Token 供应量
createPerDay = div(
sub(sub(totalSupply, foundersAllocation), createFirstDay),
numberOfDays
);
...
}
wmul
是 dapp_math
提供的一个方法。 dapp_math 中定义两种精度:WAD
和 RAY
,分别代表 18 位和 27 位的精度。以 w 开头表示该运算精度为 18 位。
由于 solidity 里面没有 float 类型,想要乘以 0.2 可以通过 乘以 0.2 ether
实现。
初始化 Token
// src/eos.sol
function initialize(DSToken eos) auth {
...
EOS = eos;
// 设置供应总量
EOS.mint(totalSupply);
// 保留 Token 发往 0xb1 这个地址
EOS.push(0xb1, foundersAllocation);
keys[0xb1] = foundersKey;
}
mint
方法是 dapp_token 提供,用来设置 Token 供应总量。
开发团队保留的份额被发送到 0xb1
。这个地址是无人可用的,等于丢掉此数量的 Token ,但是又保证 Token 总供应量不变。EOS 团队不需要这个代币,因为在 EOS 上线之后,现在的 Token 会兑换为 EOS 链上的 Token。
window time
// Each window is 23 hours long so that end-of-window rotates
// around the clock for all timezones.
function dayFor(uint timestamp) constant returns (uint) {
return timestamp < startTime
? 0
: sub(timestamp, startTime) / 23 hours + 1;
}
前五天都是 window 0 。之后每23小时为一个 window 。这么做的好处是让每个 window 的开始时间是滚动的,不同时区的投资者更方便参与。
购买逻辑
function buyWithLimit(uint day, uint limit) payable {
// 限制时间
assert(time() >= openTime && today() <= numberOfDays);
// 最小购买额度 0.01 ether
assert(msg.value >= 0.01 ether);
// 购买记录
userBuys[day][msg.sender] += msg.value;
dailyTotals[day] += msg.value;
}
Token 兑换
function claim(uint day) {
// 防止重复兑换
if (claimed[day][msg.sender] || dailyTotals[day] == 0) {
return;
}
// This will have small rounding errors, but the token is
// going to be truncated to 8 decimal places or less anyway
// when launched on its own chain.
var dailyTotal = cast(dailyTotals[day]);
var userTotal = cast(userBuys[day][msg.sender]);
// 指定 window 的 Token 供应量除以此 window 的 eth 总量
// 得到兑换比例
var price = wdiv(cast(createOnDay(day)), dailyTotal);
// 兑换比例乘以指定 window 中此用户支付的 eth 数量得到兑换总量
var reward = wmul(price, userTotal);
// 记录兑换标志
claimed[day][msg.sender] = true;
// 执行转账
EOS.push(msg.sender, reward);
}
注册 EOS 共钥
function register(string key) {
// 众筹结束之后不再提供注册
assert(today() <= numberOfDays + 1);
assert(bytes(key).length <= 64);
keys[msg.sender] = key;
}
EOS 团队要求投资者在众筹结束之前自行生成 EOS 公私钥,并将生成的共钥注册在合约中。这样在 EOS 正式上线之后,用户可以兑换 EOS 上的 Token 。
ETH 转移
function collect() auth {
// window 0 不能转移
assert(today() > 0);
// 将 eth 转移给调用者
exec(msg.sender, this.balance);
}
auth
是 dapp_auth 提供的权限控制方法,保证 collect
函数只能被合约 owner 执行。
安全性分析
EOS 众筹合约使用了 dapp_auth 提供的权限控制功能。
// src/eos.sol
// 继承 DSAuth
contract EOSSale is DSAuth {
}
// lib/ds-auth/src/auth.sol
contract DSAuth is DSAuthEvents {
DSAuthority public authority;
address public owner;
function DSAuth() {
owner = msg.sender;
}
}
DSAuth
提供的默认权限控制是基于 owner 的。默认初始化行为将合约创建者设置为 owner 。同时提供 setOwner
函数,可以转移控制权。
function setOwner(address owner_)
auth
{
owner = owner_;
LogSetOwner(owner);
}
setOwner
也需要使用 auth
验证权限。
modifier auth {
assert(isAuthorized(msg.sender, msg.sig));
_;
}
function isAuthorized(address src, bytes4 sig)
internal returns (bool)
{
// 如果调用者是合约自己,通过。
if (src == address(this)) {
return true;
// 如果调用者是 owner ,通过。
} else if (src == owner) {
return true;
// 如果 authority 未设置,失败。
} else if (authority == DSAuthority(0)) {
return false;
} else {
// 检查调用者是否有权限。
return authority.canCall(src, this, sig);
}
}
在默认行为下 authority 未设置,所以只有 owner 验证。
可以看到,这个合约还可以通过设置自定义的 DSAuthority 来扩展权限验证的逻辑。
contract DSAuthority {
function canCall(
address src, address dst, bytes4 sig
) constant returns (bool);
}
contract DSAuth is DSAuthEvents {
function setAuthority(DSAuthority authority_)
auth
{
authority = authority_;
LogSetAuthority(authority);
}
}
我们只需要在自己的合约中继承 DSAuthority ,实现 canCall 方法。
然后将实例传入 setAuthority 就可以设置特定的权限逻辑。
商业价值分析
EOS 的主要特性:
- 免费试用
- 合约可以升级
- 出块速度快,达到平均 1.5s
- 串行/并行性能强,可以达到百万级交易处理规模
- 账户系统,权限系统等
- 可插拔的合约虚拟机
EOS 更方便创建大型高频的分布式应用。
Nice
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Very cool post, I can learn a lot of new things from you :D
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
happy to follow you
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
What is this? xd :D
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
我从不买iCO
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Postnya very useful and hope you are lucky for future in this steemit :)
But do not forget the upvote on my blog too :D
#Thank's
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Toooo long to read everything :D
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Thanks for sharing, nice
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
強大的技術貼
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
有深度的技术贴,棒棒哒
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Please where can I find an English version so I can learn more about it. Thanks
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
i agree.. everything is correct
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
This post not only gives you upvotes but also this great post will give you blessings and wishes of people because with this writing many people will understand the reason for lost payment, steemit community do not forget comments, upvoting, replies, and follow me @jakir
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
写的太好了,认真看了两遍,学到很多,谢谢博主!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
I don't know guys if this real https://steemit.com/cryptocurrency/@turlx/am-i-too-late-for-the-cryptocurrency-boom
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
universal language, programming code
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
很赞,楼主深入研究过dapp提供的api啊
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Great input. Thank you for sharing!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
不错。建议加几个标签 #cn #cn-programming
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
ok
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
with translation and English all is good .... upvoted
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Thank you very much for this post.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Great topic
I look forward to more topic
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Programming codes are used by all and makes your post valuable to us Thanks
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Good post
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
HEY! GREAT WORK SIR!
You're THE KINDA MAN WHO WOULD LOVE TO KNOW WHO the freedom WHALE IS, right?:)
I exposed him, feel free to check !
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Im asian but not chinese. whats the point of being asian, right?
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Nice
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Resteem and UpVote with pleasure
(ᵔᴥᵔ) from @burundel
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
❤️
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
some english translations please? thanks
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Thank you for the translation and info :-)
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
i can see the script but cant understand, anyhow good post with good motions.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Good information!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit