学习测试ICO合约 / 学习智能合约#10

ico2.jpg

有了前面ERC20代币和智能合约的基础,再来试试ICO合约就会比较轻松地搞定。ICO合约主要是增加了一些复合性和操作的逻辑性,难度上并没有多少增加。

ICO合约的本质就是你给它发以太币,它给你发代币! ERC20代币在前面试过,实现一些标准的函数即可。ICO合约就是在一定的逻辑基础上将这些ERC20代币换成以太币。大家各取所需,皆大欢喜。

ICO合约最主要的是一个互换的函数(卖币),这里需要使用前一篇讲到的接口来调用ERC20代币合约,也就这点稍显复杂。

具体代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
pragma solidity >=0.4.22 <0.7.0;


interface token {
function transfer(address receiver, uint amount) external ;
//代币合约的接口
}

contract Ico {
address payable public beneficiary;
uint public fundingGoal;
uint public amountRaised;

uint public deadline;
uint public price;
token public tokenReward;

mapping(address => uint256) public balanceOf;
bool crowdsaleClosed = false;

event GoalReached(address recipient, uint totalAmountRaised);
event FundTransfer(address backer, uint amount, bool isContribution);

constructor (
uint fundingGoalInEthers,
uint durationInMinutes,
uint etherCostOfEachToken,
address addressOfTokenUsedAsReward
) public {
beneficiary = msg.sender;
fundingGoal = fundingGoalInEthers * 1 ether;
deadline = now + durationInMinutes * 1 minutes;
price = etherCostOfEachToken * 1 ether;
tokenReward = token(addressOfTokenUsedAsReward); //代币合约地址,以接口形式实现
}

receive() external payable {
//给合约转以太币以换取代币
require(!crowdsaleClosed);
uint amount = msg.value;
balanceOf[msg.sender] += amount;
amountRaised += amount;
tokenReward.transfer(msg.sender, amount / price);
emit FundTransfer(msg.sender, amount, true);
}

fallback () external payable { }

modifier afterDeadline() {
if (now >= deadline) {
_;
}
}

function checkGoalReached() public afterDeadline {
if (amountRaised >= fundingGoal) {
emit GoalReached(beneficiary, amountRaised);
}
crowdsaleClosed = true;
}


function safeWithdrawal() public afterDeadline {
if (amountRaised < fundingGoal) {
uint amount = balanceOf[msg.sender];
balanceOf[msg.sender] = 0;
if (amount > 0) {
msg.sender.transfer(amount);
emit FundTransfer(msg.sender, amount, false);
}
}

if (fundingGoal <= amountRaised && beneficiary == msg.sender) {
beneficiary.transfer(amountRaised);
emit FundTransfer(beneficiary, amountRaised, false);
}
}

function getEthBalance(address addr) public view returns (uint) {
return addr.balance;
}
}

新版的Solidity更新了不少的代码规范,我参考网上的文章做了不少改进,有兴趣的朋友不妨也来测试下。


This page is synchronized from the post: ‘学习测试ICO合约 / 学习智能合约#10’

智能合约的封装,继承和多态 / 学习智能合约#9

智能合约

智能合约的封装,继承和多态,之所以这么提,是因为智能合约和面向对象实在是太像了,两者几乎是长得一模一样!

面向对象三大特性是:封装,继承,多态

所谓封装:
也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

所谓继承:
是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

所谓多态:
就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。

对比着看:

  1. 智能合约的封装:
    关键词:public private external internal
    可以访问,可以继承的是public external
    只能内部访问,不可继承的是private internal

  2. 智能合约的继承:
    contract ERC20 is ERC20Interface{}
    关键词: is

  3. 智能合约的多态
    多态稍显复杂点,在智能合约中是通过抽象合约来实现类似多态的功能。一个抽象合约被多个合约继承,对其方法可以有不同的实现。
    注意:两个合约间只是方法的实现,不会相互改变状态变量等。
    来个合约详情的例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    pragma solidity >0.4.23 <0.7.0;

    abstract contract AbstractContract {
    function add(uint m, uint n) public virtual returns(uint);
    function mul(uint m, uint n) public pure returns(uint) {
    return m * n;
    }
    }

    contract MyContract is AbstractContract {
    function add(uint m, uint n) public override returns(uint) {
    return m + n;
    }
    }


    contract MyContract2 is AbstractContract {
    function add(uint m, uint n) public override returns(uint) {
    return (m + n) * 2;
    }
    }


    contract NewContract {
    AbstractContract c = new MyContract2();
    //合约的实例化以实现不同合约中的方法
    function calc(uint m, uint n) public returns(uint) {
    return c.add(m,n) + c.mul(m,n);
    }
    }

总体来讲,智能合约的功能还是比较丰富的,不过局限于存储的区块链,有很多特别细致的讲究,以至于学起来过于复杂。但是为了得到全网一致性的共识,有些性能被牺牲了,这也是可以理解的。


This page is synchronized from the post: ‘智能合约的封装,继承和多态 / 学习智能合约#9’

KeyShot快速渲染

https://steemjiang.com:8081/ipfs/QmbY1VBjSAQvjop2JLUyYmJDXu1Bveo8FpRoVGmLBmuu4B

KeyShot的快速入门教程。课程包括产品渲染三部曲,KeyShot的基本介绍和材质,几个渲染案例。通过此课程可以快速把握KeyShot的基本技能,能够快速渲染出生产级的产品图片。
-> 前往链课


This page is synchronized from the post: ‘KeyShot快速渲染’

新技能:移动电源启动汽车

battery.jpg

疫情原因,学校封闭得很严。车停得久了,突然间就无法启动了。电话咨询了一下,应该是汽车电池的原因。本想找个师傅过来弄下,又碍于学校的严管政策,不是很方便进来,那就只能自己想办法了。

前些日子看到村长也聊过这事,汽车电池坏了打不着火。看他是用了移动电源,我也到京东上找找。

battery2.jpg

移动电源看起来不错,一机多用!即可用于汽车打火,平时还可用于手机充电。嗯,就它了!

买了后兴冲冲地去试了下!结果是大失所望,连续启动数次还是不行,电池也一下就没电了!还是得去找找原因啊,不可能别人行而我不行的。倒真有个原因我没有仔细看到:如果电瓶严重亏电,使用移动电源打火时,应先将电瓶负极先取下来,以防止电源倒吸!想想,好像有点道理:原电池严重亏电会先从移动电源这吸点电,导致启动时电流不够!

将移动电源充满电后再去试试!将原电池负极先取下来,接上移动电源,打了两下,奇迹般地打着了!看来,知识改变做法啊。有同样困难的朋友不妨照着试试。


This page is synchronized from the post: ‘新技能:移动电源启动汽车’

试试投票合约 / 学习智能合约#8

voting.jpg

在16年的时候很多人嘲笑以太坊的功能弱:也就能用在小学生选班长上! Solidity语言中就把这个选班长合约做成一个经典案例了。

找到相关的合约代码研究了下,发现还蛮复杂的。一时间还不知从何入手呢。

去掉些复杂的条件,找到最核心的东东,试了试,还蛮顺利地就实现了。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
pragma solidity >0.4.23 <0.7.0;

contract Voting {
mapping (string => uint ) public votesReceived;
mapping (address => bool) private addrRecoded;
string[] public candidateList = ["lemool", "jackey", "hello"];

function totalVotesFor(string memory candidate) view public returns (uint) {
return votesReceived[candidate];
}

function voteForCandidate(string memory candidate) payable public {
require(!addrRecoded[msg.sender]);
addrRecoded[msg.sender] = true;
uint m = msg.value / 0.1 ether;
votesReceived[candidate] += m;
}
}

做几点说明:

  1. 将候选人类型设为了”string” 而不是”bytes32”,这样可以很方便地交互。”bytes32”是个大坑,现在新版的必须将字符串转成十六过制类型才能存入,否则一个劲地报错!
  2. 投票合约和代币一样,就是做个表格记录候选人的票数,理解这点就很简单了。其它的附加条件可以先不用。
  3. 投票通过”msg.value”来收费,0.1个币一票,充分体现什么叫资本主义。

This page is synchronized from the post: ‘试试投票合约 / 学习智能合约#8’

广州暴雨,水漫金山

subway.jpg

好像每年这个时候广州都要被淹几次!

这几天又是连续几场暴雨,下得人是心肝颤啊,真是大到没边了。我是整天呆在家都提心吊胆的,不过好像也没什么值得我担心的啊。去年没留意,车停在低洼处,结果中招了。结果是现在每每车都停在高地,就是要多走几步了。

在网上随意一翻,又是一堆被淹的消息。倒不是广州排水不给力,而是降雨量着实太大!如果没有亲身体会,是有点难理解什么叫倾盆大雨!短短几个小时内就是上百毫米的降雨!你要知道新疆年降雨量也才150毫米。也就是说广州两小时的雨量够新疆下一年的!

碰到这些个情况也没啥办法。我等吃瓜群众也就是跟着看看情况,多多留意。


This page is synchronized from the post: ‘广州暴雨,水漫金山’

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×