【Solidity】学习(4)
solidity函数修饰符
view 没有改变任何值或者写任何东西。只能读取,不能修改
function sayHello() public view returns (string) { }
pure 函数不访问应用里的数据
第11章: Keccak256 和 类型转换
//6e91ec6b618bb462a4a6ee5aa2cb0e9cf30f7a052bb467b0ba58b8748c00d2e5 keccak256("aaaab"); //b1f078126895a1424524de5321b339ab00408010b7cf0e6ed451514981e58aa9 keccak256("aaaac"); //可以发现,只是改变一个字符,散列值变化就很大 //注: 在区块链中安全地产生一个随机数是一个很难的问题, 本例的方法不安全,但是在我们的Zombie DNA算法里不是那么重要,已经很好地满足我们的需要了。
类型转换
function _generateRandomDna(string _str) private view returns (uint) { //注意uint写在()外面,不同于cpp uint rand = uint(keccak256(_str)); return rand % dnaModulus; }
require
require
使得函数在执行过程中,当不满足某些条件时抛出错误,并停止执行
function sayHiToVitalik(string _name) public returns (string) { // 比较 _name 是否等于 "Vitalik". 如果不成立,抛出异常并终止程序 // (敲黑板: Solidity 并不支持原生的字符串比较, 我们只能通过比较 // 两字符串的 keccak256 哈希值来进行判断) require(keccak256(_name) == keccak256("Vitalik")); // 如果返回 true, 运行如下语句 return "Hi!"; }
import
在 Solidity 中,当你有多个文件并且想把一个文件导入另一个文件时,可以使用 import
语句
import "./someothercontract.sol";
//注意引号和分号 //当我们在合约(contract)目录下有一个名为 someothercontract.sol 的文件( ./ 就是同一目录的意思),它就会被编译器导入 contract newContract is SomeOtherContract { }
memory和storage
Storage 变量是指永久存储在区块链中的变量。 Memory 变量则是临时的,当外部函数对某合约调用完成时,内存型变量即被移除。 你可以把它想象成存储在你电脑的硬盘或是RAM中数据的关系。
大多数时候你都用不到这些关键字,默认情况下 Solidity 会自动处理它们。 状态变量(在函数之外声明的变量)默认为“存储”形式,并永久写入区块链;而在函数内部声明的变量是“内存”型的,它们函数调用结束后消失。
然而也有一些情况下,你需要手动声明存储类型,主要用于处理函数内的 _ 结构体 _ 和 _ 数组 _ 时:
contract SandwichFactory { struct Sandwich { string name; string status; } Sandwich[] sandwiches; function eatSandwich(uint _index) public { // Sandwich mySandwich = sandwiches[_index]; // ^ 看上去很直接,不过 Solidity 将会给出警告 // 告诉你应该明确在这里定义 `storage` 或者 `memory`。 // 所以你应该明确定义 `storage`: Sandwich storage mySandwich = sandwiches[_index]; // ...这样 `mySandwich` 是指向 `sandwiches[_index]`的指针 // 在存储里,另外... mySandwich.status = "Eaten!"; // ...这将永久把 `sandwiches[_index]` 变为区块链上的存储 // 如果你只想要一个副本,可以使用`memory`: Sandwich memory anotherSandwich = sandwiches[_index + 1]; // ...这样 `anotherSandwich` 就仅仅是一个内存里的副本了 // 另外 anotherSandwich.status = "Eaten!"; // ...将仅仅修改临时变量,对 `sandwiches[_index + 1]` 没有任何影响 // 不过你可以这样做: sandwiches[_index + 1] = anotherSandwich; // ...如果你想把副本的改动保存回区块链存储 } }