Solidity是一种智能合约高级语言,运行在Ethereum虚拟机(EVM)之上。
Solidity与其它语言相关的特点?
它的语法接近于Javascript,是一种面向对象的语言。但作为一种真正意义上运行在网络上的去中心合约,它又有很多的不同,下面列举一些:
以太坊底层是基于帐户,而非UTXO的,所以有一个特殊的Address的类型。用于定位用户,定位合约,定位合约的代码(合约本身也是一个帐户)。
由于语言内嵌框架是支持支付的,所以提供了一些关键字,如payable,可以在语言层面直接支持支付,而且超级简单。
存储是使用网络上的区块链,数据的每一个状态都可以永久存储,所以需要确定变量使用内存,还是区块链。
运行环境是在去中心化的网络上,会比较强调合约或函数执行的调用的方式。因为原来一个简单的函数调用变为了一个网络上的节点中的代码执行,分布式的感觉。
最后一个非常大的不同则是它的异常机制,一旦出现异常,所有的执行都将会被回撤,这主要是为了保证合约执行的原子性,以避免中间状态出现的数据不一致。
Hello Wolrd!
听起来高大上,其实入手玩起来也可以很简单:
pragma solidity ^0.4.0;
contract HelloWorld{
uint balance;
function update(uint amount) returns (address, uint){
balance += amount;
return (msg.sender, balance);
}
}
通过读取参数输入的新值,并将之累加至合约的变量中,返回发送人的地址,和最终的累计值。
1.Solidity智能合约文件结构
版本申明
pragma solidity ^0.4.0;
说明:
1 版本要高于0.4才可以编译
2 号表示高于0.5的版本则不可编译,第三位的版本号但可以变,留出来用做bug可以修复(如0.4.1的编译器有bug,可在0.4.2修复,现有合约不用改代码)。
引用其它源文件
全局引入 *
import “filename”;
自定义命名空间引入 *
import * as symbolName from “filename”
分别定义引入
import {symbol1 as alias, symbol2} from “filename”
非es6兼容的简写语法
import “filename” as symbolName
等同于上述
import * as symbolName from “filename”
关于路径
引入文件路径时要注意,非.打头的路径会被认为是绝对路径,所以要引用同目录下的文件使用
import “./x” as x
也不要使用下述方式,这样会是在一个全局的目录下
import “x” as x;
为什么会有这个区别,是因为这取决于编译器,如果解析路径,通常来说目录层级结构并不与我们本地的文件一一对应,它非常有可能是通过ipfs,http,或git建立的一个网络上的虚拟目录。
编译器解析引用文件机制
各编译器提供了文件前缀映射机制。
1. 可以将一个域名下的文件映射到本地,从而从本地的某个文件中读取
2. 提供对同一实现的不同版本的支持(可能某版本的实现前后不兼容,需要区分)
3. 如果前缀相同,取最长,
4. 有一个”fallback-remapping”机制,空串会映射到“/usr/local/include/solidify”
solc编译器
命令行编译器,通过下述命令命名空间映射提供支持
context:prefix=target
上述的context:和=target是可选的。所有context目录下的以prefix开头的会被替换为target。
举例来说,如果你将github.com/ethereum/dapp-bin拷到本地的/usr/local/dapp-bin,并使用下述方式使用文件
import “github.com/ethereum/dapp-bin/library/iterable_mapping.sol” as it_mapping;
要编译这个文件,使用下述命令:
solc github.com/ethereum/dapp-bin=/usr/local/dapp-bin source.sol
另一个更复杂的例子,如果你使用一个更旧版本的dapp-bin,旧版本在/url/local/dapp-bin_old,那么,你可以使用下述命令编译
solc module1:github.com/ethereum/dapp-bin=/usr/local/dapp-bin \
modeule2:github.com/ethereum/dapp-bin=/usr/local/dapp-bin_old \
source.sol
需要注意的是solc仅仅允许包含实际存在的文件。它必须存在于你重映射后目录里,或其子目录里。如果你想包含直接的绝对路径包含,那么可以将命名空间重映射为=\
备注:如果有多个重映射指向了同一个文件,那么取最长的那个文件。
browser-solidity编译器:
browser-solidity编译器默认会自动映射到github上,然后会自动从网络上检索文件。例如:你可以通过下述方式引入一个迭代包:
import “github.com/ethereum/dapp-bin/library/iterable_mapping.sol” as it_mapping
备注:未来可能会支持其它的源码方式
代码注释
两种方式,单行(//),多行使用(/*…*/)
文档注释
写文档用。三个斜杠///或/** … */,可使用Doxygen语法,以支持生成对文档的说明,参数验证的注解,或者是在用户调用这个函数时,弹出来的确认内容。
2.值类型与引用类型
每个合约中可包含状态变量(State Variables),函数(Functions),函数修饰符(Function Modifiers),事件(Events),结构类型(Structs Types)和枚举类型(Enum Types)。
值类型(Value Type)
值类型包含
布尔(Booleans)
整型(Integer)
地址(Address)
定长字节数组(fixed byte arrays)
有理数和整型(Rat
Solidity与其它语言相关的特点?
它的语法接近于Javascript,是一种面向对象的语言。但作为一种真正意义上运行在网络上的去中心合约,它又有很多的不同,下面列举一些:
以太坊底层是基于帐户,而非UTXO的,所以有一个特殊的Address的类型。用于定位用户,定位合约,定位合约的代码(合约本身也是一个帐户)。
由于语言内嵌框架是支持支付的,所以提供了一些关键字,如payable,可以在语言层面直接支持支付,而且超级简单。
存储是使用网络上的区块链,数据的每一个状态都可以永久存储,所以需要确定变量使用内存,还是区块链。
运行环境是在去中心化的网络上,会比较强调合约或函数执行的调用的方式。因为原来一个简单的函数调用变为了一个网络上的节点中的代码执行,分布式的感觉。
最后一个非常大的不同则是它的异常机制,一旦出现异常,所有的执行都将会被回撤,这主要是为了保证合约执行的原子性,以避免中间状态出现的数据不一致。
Hello Wolrd!
听起来高大上,其实入手玩起来也可以很简单:
pragma solidity ^0.4.0;
contract HelloWorld{
uint balance;
function update(uint amount) returns (address, uint){
balance += amount;
return (msg.sender, balance);
}
}
通过读取参数输入的新值,并将之累加至合约的变量中,返回发送人的地址,和最终的累计值。
1.Solidity智能合约文件结构
版本申明
pragma solidity ^0.4.0;
说明:
1 版本要高于0.4才可以编译
2 号表示高于0.5的版本则不可编译,第三位的版本号但可以变,留出来用做bug可以修复(如0.4.1的编译器有bug,可在0.4.2修复,现有合约不用改代码)。
引用其它源文件
全局引入 *
import “filename”;
自定义命名空间引入 *
import * as symbolName from “filename”
分别定义引入
import {symbol1 as alias, symbol2} from “filename”
非es6兼容的简写语法
import “filename” as symbolName
等同于上述
import * as symbolName from “filename”
关于路径
引入文件路径时要注意,非.打头的路径会被认为是绝对路径,所以要引用同目录下的文件使用
import “./x” as x
也不要使用下述方式,这样会是在一个全局的目录下
import “x” as x;
为什么会有这个区别,是因为这取决于编译器,如果解析路径,通常来说目录层级结构并不与我们本地的文件一一对应,它非常有可能是通过ipfs,http,或git建立的一个网络上的虚拟目录。
编译器解析引用文件机制
各编译器提供了文件前缀映射机制。
1. 可以将一个域名下的文件映射到本地,从而从本地的某个文件中读取
2. 提供对同一实现的不同版本的支持(可能某版本的实现前后不兼容,需要区分)
3. 如果前缀相同,取最长,
4. 有一个”fallback-remapping”机制,空串会映射到“/usr/local/include/solidify”
solc编译器
命令行编译器,通过下述命令命名空间映射提供支持
context:prefix=target
上述的context:和=target是可选的。所有context目录下的以prefix开头的会被替换为target。
举例来说,如果你将github.com/ethereum/dapp-bin拷到本地的/usr/local/dapp-bin,并使用下述方式使用文件
import “github.com/ethereum/dapp-bin/library/iterable_mapping.sol” as it_mapping;
要编译这个文件,使用下述命令:
solc github.com/ethereum/dapp-bin=/usr/local/dapp-bin source.sol
另一个更复杂的例子,如果你使用一个更旧版本的dapp-bin,旧版本在/url/local/dapp-bin_old,那么,你可以使用下述命令编译
solc module1:github.com/ethereum/dapp-bin=/usr/local/dapp-bin \
modeule2:github.com/ethereum/dapp-bin=/usr/local/dapp-bin_old \
source.sol
需要注意的是solc仅仅允许包含实际存在的文件。它必须存在于你重映射后目录里,或其子目录里。如果你想包含直接的绝对路径包含,那么可以将命名空间重映射为=\
备注:如果有多个重映射指向了同一个文件,那么取最长的那个文件。
browser-solidity编译器:
browser-solidity编译器默认会自动映射到github上,然后会自动从网络上检索文件。例如:你可以通过下述方式引入一个迭代包:
import “github.com/ethereum/dapp-bin/library/iterable_mapping.sol” as it_mapping
备注:未来可能会支持其它的源码方式
代码注释
两种方式,单行(//),多行使用(/*…*/)
文档注释
写文档用。三个斜杠///或/** … */,可使用Doxygen语法,以支持生成对文档的说明,参数验证的注解,或者是在用户调用这个函数时,弹出来的确认内容。
2.值类型与引用类型
每个合约中可包含状态变量(State Variables),函数(Functions),函数修饰符(Function Modifiers),事件(Events),结构类型(Structs Types)和枚举类型(Enum Types)。
值类型(Value Type)
值类型包含
布尔(Booleans)
整型(Integer)
地址(Address)
定长字节数组(fixed byte arrays)
有理数和整型(Rat