Solidaty学习笔记(二)
函数修饰符modifier()
可以自定义其对函数的约束逻辑,这些修饰符可以同时作用域一个函数定义上。modifier修饰函数时也可以带参数。
记住,修饰符的最后一行为 _;,表示修饰符调用结束后返回,并执行调用函数余下的部分。
既然说到这里了,就来复习下前两天刚看到的其他函数修饰符吧(阴险):
可见性修饰符:
private:只能被合约内部调用。
internal:只能被合约内部调用这或者被继承的合约调用。
public:可以在任何地方调用,不管是内部还是外部。
external:只能从合约外部调用。
状态修饰符:
view:运行这个函数不会更改和保存任何数据。
pure:运行这个函数不会往区块链写数据,甚至不会从区块链读取数据。
这两种在被外部合约调用的时候都不花费任何gas,但是它们被内部其它函数调用的时候会耗费gas。
payable修饰符:
可以接受以太的特殊函数。
contract OnlineStore {
function buySomething() external payable {
// 检查以确定0.001以太发送出去来运行函数:
require(msg.value == 0.001 ether);
// 如果为真,一些用来向函数调用者发送数字内容的逻辑
transferThing(msg.sender);
}
}
注意: 如果一个函数没标记为payable, 而你尝试利用上面的方法发送以太,函数将拒绝你的事务。
Gas
以太坊Gas是用来衡量诸如完成交易或执行智能合约等计算任务的成本,它的计价单位是小额以太币Gwei。Gas用来给以太坊虚拟机分配资源,使智能合约得以自主执行。
省Gas————结构封装(Struct Packing)
顾名思义,就是把uint绑定到struct里面。
在内存中声明数组,即在数组后面加上memory关键字,表明这个数组是仅仅在内存中创建,不需要写入外部存储,并且在函数调用结束时它就解散了。与在程序结束时把数据保存进 storage 的做法相比,内存运算可以大大节省gas开销——把这数组放在view里用,完全不用花钱。例如:
function getArray() external pure returns(uint[]) {
// 初始化一个长度为3的内存数组
uint[] memory values = new uint[](3);
// 赋值
values.push(1);
values.push(2);
values.push(3);
// 返回数组
return values;
}
solidaty时间单位
变量now将返回当前的unix时间戳(自1970年1月1日来经过的秒数)。
注意:now返回类型是uint256,必要的时候需要强转类型。
for循环
看例子:
function getEvens() pure external returns(uint[]) {
uint[] memory evens = new uint[](5);
// 在新数组中记录序列号
uint counter = 0;
// 在循环从1迭代到10:
for (uint i = 1; i <= 10; i++) {
// 如果 `i` 是偶数...
if (i % 2 == 0) {
// 把它加入偶数数组
evens[counter] = i;
//索引加一, 指向下一个空的‘even’
counter++;
}
}
return evens;
}
随机数
用随机数生成器leccak256哈希函数来制造随机数,
//生成一个0-100的随机数
uint randNonce = 0;
randNounce ++;
uint random2 = uint(keccak256(now, msg.sender, randNonce)) % 100;
这个方法首先拿到 now 的时间戳、 msg.sender、 以及一个自增数 nonce (一个仅会被使用一次的数,这样我们就不会对相同的输入值调用一次以上哈希函数了)。
以太坊上的代币
ERC20代币
理解:
在以太坊系统中,存在作为基础货币的 Ether(以太),以及同样可以作为货币使用的 Token(代币)。
以太坊不是单纯的货币,而是一个环境/平台。在这个平台上,任何人都可以利用区块链的技术,通过智能合约来构建自己的项目和DAPPS(去中心化应用)。
如果把以太坊理解成互联网,DAPPS则是在上面运行的网页。DAPPS是去中心化的,意味着它不属于某个人,而是属于一群人。DAPPS发布的方式通常是采用被称为 ICO 的众筹方式。简单来说,你需要用你的以太来购买相应DAPP的一些tokens。
ERC-20 标准是在2015年11月份推出的,使用这种规则的代币,表现出一种通用的和可预测的方式。任何 ERC-20 代币都能立即兼容以太坊钱包(几乎所有支持以太币的钱包,包括Jaxx、MEW、imToken等),由于交易所已经知道这些代币是如何操作的,它们可以很容易地整合这些代币。这就意味着,在很多情况下,这些代币都是可以立即进行交易的。简单理解就是,ERC20是开发者在自己的tokens中必须采用的一套具体的公式/方法,从而确保不同DAPP的token与ERC20标准兼容。
一般有两种Token:
- Usage Tokens
对应DAPP的原生货币。例如,Golem。如果你需要使用 Golem 的服务,你就需要为其支付 Golem Network Token(GNT)。由于这种 Tokens 有货币价值,所以通常不会有其他的权益。
- Work Tokens
可以标识你对于DAPP的某种股东权益。以DAO Tokens为例,如果你拥有DAO Tokens,那么你有权针对DAO是否资助某款 DAPP 来进行投票。
ERC 20标准接口:
contract ERC20 {
uint256 public totalSupply;
function balanceOf(address who) constant public returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
function allowance(address owner, address spender) constant public returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
函数说明:
-
totalSupply: 返回token的总供应量
-
balanceOf: 用于查询某个账户的账户余额
-
tansfer: 发送 _value 个 token 到地址 _to
-
transferFrom: 从地址 _from 发送 _value 个
-
token 到地址 _to
-
approve: 允许 _spender 多次取回您的帐户,最高达 _value 金额; 如果再次调用此函数,它将用 _value 的当前值覆盖的 allowance 值。
-
allowance: 返回 _spender 仍然被允许从 _owner 提取的金额。
事件说明:
-
event Transfer: 当 tokens 被转移时触发。
-
event Approval: 当任何成功调用 approve(address _spender, uint256 _value) 后,必须被触发。
代币
一个 代币 在以太坊基本上就是一个遵循一些共同规则的智能合约——即它实现了所有其他代币合约共享的一组标准函数,例如 transfer(address _to, uint256 _value) 和 balanceOf(address _owner).
在智能合约内部,通常有一个映射, mapping(address => uint256) balances,用于追踪每个地址还有多少余额。
所以基本上一个代币只是一个追踪谁拥有多少该代币的合约,和一些可以让那些用户将他们的代币转移到其他地址的函数。
** 其他说明:**
由于所有 ERC20 代币共享具有相同名称的同一组函数,它们都可以以相同的方式进行交互。
这意味着如果你构建的应用程序能够与一个 ERC20 代币进行交互,那么它就也能够与任何 ERC20 代币进行交互。 这样一来,将来你就可以轻松地将更多的代币添加到你的应用中,而无需进行自定义编码。 你可以简单地插入新的代币合约地址,然后哗啦,你的应用程序有另一个它可以使用的代币了。
其中一个例子就是交易所。 当交易所添加一个新的 ERC20 代币时,实际上它只需要添加与之对话的另一个智能合约。 用户可以让那个合约将代币发送到交易所的钱包地址,然后交易所可以让合约在用户要求取款时将代币发送回给他们。
交易所只需要实现这种转移逻辑一次,然后当它想要添加一个新的 ERC20 代币时,只需将新的合约地址添加到它的数据库即可。
ERC721 代币
有另一个代币标准更适合如 CryptoZombies 这样的加密收藏品——它们被称为ERC721 代币。ERC721代币是不能互换的,因为每个代币都会被认为是唯一并且不可分割的。只能以整个单位交易它们,并且每个单位都有唯一的 ID。