20230311区块链基础及eth链特性和Solidity特性

Blockchain Basics 区块链基础

Blockchains as a concept are not too hard to understand for programmers. The reason is that most of the complications (mining, hashing, elliptic-curve cryptography, peer-to-peer networks, etc.) are just there to provide a certain set of features and promises for the platform.

Once you accept these features as given, you do not have to worry about the underlying technology - or do you have to know how Amazon’s AWS works internally in order to use it?

对于程序员来说,区块链的概念并不是特别难理解, 原因就是这些所有的问题(挖矿,哈希,椭圆曲线加密,点对点网络等等)对于他们来说就是提供了一个特定集合的特性以及预期的平台.

一点你接受了上述这些特性,你就没有必要去担心这些底层的技术细节,正如你去使用aws的时候不需要关系亚马逊aws的内部工作原理一样.

Transaction

A blockchain is a globally shared, transactional database. This means that everyone can read entries in the database just by participating in the network. If you want to change something in the database, you have to create a so-called transaction which has to be accepted by all others. The word transaction implies that the change you want to make (assume you want to change two values at the same time) is either not done at all or completely applied. Furthermore, while your transaction is being applied to the database, no other transaction can alter it.

As an example, imagine a table that lists the balances of all accounts in an electronic currency. If a transfer from one account to another is requested, the transactional nature of the database ensures that if the amount is subtracted from one account, it is always added to the other account. If due to whatever reason, adding the amount to the target account is not possible, the source account is also not modified.

Furthermore, a transaction is always cryptographically signed by the sender (creator). This makes it straightforward to guard access to specific modifications of the database. In the example of the electronic currency, a simple check ensures that only the person holding the keys to the account can transfer money from it.

区块链是一个全局共享的事务型数据库. 这就意味着所有人都可以通过加入到这个网络中来访问这个数据库. 如果你想改变这个数据库的某个东西,那么你必须要创建一个必须为其他所有人所接受的称之为事务的东西. 事务这个词意味着你想做出的改变(假设你想在同一时间变更两个值)要么没成功,要么完全成功. 此外,一旦你的事务在这个数据库中生效了,那么就没有其他事务可以修改它.

举个例子吧, 想象一下在一个电子货币系统重,你列出了所有账户的余额.  如果有一笔转账请求发起, 那么这个数据库事务性的特性就保证了,

一个账户减少多少金额,那么这部分金额就会相应的增加到另一个账户中. 如果由于任何原因导致了增加金额到特定账户不可能,那么原账户也将不会修改.

更近一步的,每一个事务总是由发起者或者说创建者通过密码签名的,这就直接了当的保证对数据库的特定修改是安全的.  在电子货币的案例中,一个简单的验证确保了仅仅只有持有key的人可以从当前账户转账.

Blocks 区块

One major obstacle to overcome is what (in Bitcoin terms) is called a “double-spend attack”: What happens if two transactions exist in the network that both want to empty an account? Only one of the transactions can be valid, typically the one that is accepted first. The problem is that “first” is not an objective term in a peer-to-peer network.

一个主要需要克服的障碍就是(用比特币的术语来说)称之为双花工具:如果两个交易并存在同一个网络中,并且他们都想要清空一个账号? 而只有一个事务是合法的,

典型的做法是,第一个被接受的就是合法的. 但是问题在于在点对点网络中第一个被接受的并不是一个客观的术语

The abstract answer to this is that you do not have to care. A globally accepted order of the transactions will be selected for you, solving the conflict. The transactions will be bundled into what is called a “block” and then they will be executed and distributed among all participating nodes. If two transactions contradict each other, the one that ends up being second will be rejected and not become part of the block.

这个抽象的答案是你不需要去关注的东西.  一个全局所接受的事务顺序将会为你做出选择,解决这个冲突. 所有的交易会被打包放入到区块中,然后这个区块会被所有参与的节点执行并且分发. 如果两个交易彼此冲突,那么随后被执行的那个事务将会被拒绝,不会成为区块的一部分.

These blocks form a linear sequence in time, and that is where the word “blockchain” derives from. Blocks are added to the chain at regular intervals, although these intervals may be subject to change in the future. For the most up-to-date information, it is recommended to monitor the network, for example, on Etherscan.

这些区块随着时间组织的线性序列,这也就是区块链一词的来源. 这些区块会被间歇性的加入到这个链条中, 尽管这些间隔时间在未来会被重新修改. 如果想获取最新的信息

建议监控整个网络,比如使用Etherscan.

As part of the “order selection mechanism” (which is called “mining”) it may happen that blocks are reverted from time to time, but only at the “tip” of the chain. The more blocks are added on top of a particular block, the less likely this block will be reverted. So it might be that your transactions are reverted and even removed from the blockchain, but the longer you wait, the less likely it will be.

作为顺序选择机制的一部分(也叫挖矿),也可能发生随着时间区块被回滚,但是仅仅出现在小链中. 对于一个特定的块来说,越多的块被加入到它,那么这个区块回归的概率就越小. 因此可能你的交易也会被回滚并且从区块链中移除,但是只要你等的时间越长,这种可能性就越小.

The Ethereum Virtual Machine

The Ethereum Virtual Machine or EVM is the runtime environment for smart contracts in Ethereum. It is not only sandboxed but actually completely isolated, which means that code running inside the EVM has no access to network, filesystem or other processes. Smart contracts even have limited access to other smart contracts.

EVM 是在以太坊网络中智能合约的运行环境.它不仅仅是沙河保护的并且是事实上的完全隔离的, 也就是说代码运行在evm内,不需要访问网络,文件系统或者其他进程.

甚至是智能合约也仅仅是可以有限的访问其他智能合约.

Accounts

There are two kinds of accounts in Ethereum which share the same address space: External accounts that are controlled by public-private key pairs (i.e. humans) and contract accounts which are controlled by the code stored together with the account.

账户的概念, 在以太坊网络中有两种类型的账户,共享共同的地址空间: 由公钥私钥对控制的外部账号(比如人),以及由跟代码存储在一起的账户共同控制的合约账户.

The address of an external account is determined from the public key while the address of a contract is determined at the time the contract is created (it is derived from the creator address and the number of transactions sent from that address, the so-called “nonce”).

外部地址又公钥决定,而合约地址是由合约创建的时候确定的(它取决于创建者地址,以及从这个地址发出的交易数量,或者我们称之为nonce)

Regardless of whether or not the account stores code, the two types are treated equally by the EVM.

不管这账户是否存储了代码,这两种类型的账号被EVM对等的处理

Every account has a persistent key-value store mapping 256-bit words to 256-bit words called storage.

每一个账户有一个永久性的键值对的存储映射,将256位字符映射到256位字符,我们称之为存储.

Furthermore, every account has a balance in Ether (in “Wei” to be exact, 1 ether is 10**18 wei) which can be modified by sending transactions that include Ether.

此外,每一个账号都会有一个以ether数量为计算的余额(确切的说是WEI,1eth=10^18),这个余额可以通过发送包含eth交易的方式进行变更.

Transactions 事务

A transaction is a message that is sent from one account to another account (which might be the same or empty, see below). It can include binary data (which is called “payload”) and Ether.

一个事务就是一个账户发给另一个账号的信息(当然另一个账户可以是自己,也可以是为空,具体见下文) 这笔事务也可以包含二进制数据(我们称之为payload收费载重)和ether代币.

If the target account contains code, that code is executed and the payload is provided as input data.

如果目标账户包好了代码,那么这个代码将被执行,同时payload将被视为输入数据.

If the target account is not set (the transaction does not have a recipient or the recipient is set to null), the transaction creates a new contract.

如果目标账号没有设置(也就是这笔事务没有收款人,或者收款人设置为空),那么这笔事务将创建一个新的合约.

As already mentioned, the address of that contract is not the zero address but an address derived from the sender and its number of transactions sent (the “nonce”).

正如前文所说的那样,这个合约地址不是一个零地址,但是它是由发送方地址和发送方发送的交易数量决定

The payload of such a contract creation transaction is taken to be EVM bytecode and executed. The output data of this execution is permanently stored as the code of the contract.

这个合约创建的事务的payload,被拿到EVM字节码并且被执行. 本次执行的输出数据被永久性的存储为合约的代码.

This means that in order to create a contract, you do not send the actual code of the contract, but in fact code that returns that code when executed.

那么也就意味着,为了创建一个合约,你不需要发送合约的实际代码,但是事实上这个代码就是执行返回的代码.

Note

While a contract is being created, its code is still empty. Because of that, you should not call back into the contract under construction until its constructor has finished executing.

请注意,当一个合约被创建的时候,其代码依旧是空的, 因此,你不应该返回调用这个合约,当这个合约正在创建过程中,直到它的构造函数已经完成执行的时候.

GAS

Upon creation, each transaction is charged with a certain amount of gas that has to be paid for by the originator of the transaction (tx.origin). While the EVM executes the transaction, the gas is gradually depleted according to specific rules. If the gas is used up at any point (i.e. it would be negative), an out-of-gas exception is triggered, which ends execution and reverts all modifications made to the state in the current call frame.

当创建的时候,每一笔事务都需要由事务的发起者去支付特定数量的gas. 当EVM执行这笔交易时,gas是根据特定的规则逐渐被消耗的. 如果这个gas在任何一个节点被使用完(例如gas为负数了),那么就会触发gas不足的异常, 这样执行将终止,在当前调用框架中所有对于状态的所有修改都将被回滚.

This mechanism incentivizes economical use of EVM execution time and also compensates EVM executors (i.e. miners / stakers) for their work. Since each block has a maximum amount of gas, it also limits the amount of work needed to validate a block.

这个机制就鼓励人民经济性的使用evm执行时间,同时也奖励了evm的执行者(比如矿工和质押人)的工作,由于每一个块都有一个最高的gas金额,因此也就限制了

验证一个块所需要的工作额.

The gas price is a value set by the originator of the transaction, who has to pay gas_price * gas up front to the EVM executor. If some gas is left after execution, it is refunded to the transaction originator. In case of an exception that reverts changes, already used up gas is not refunded.

gas price是由交易发起者设定的一个值, 这个交易执行者必须提前支付 gas price* gas数量的eth给evm 的执行者. 如果在执行完之后还有一些gas剩余,那么将会返回给交易发起者.而当异常情况,交易回滚了,那么已经花费的gas是不会被退回的.

Since EVM executors can choose to include a transaction or not, transaction senders cannot abuse the system by setting a low gas price.

因为EVM执行者可以选择包含某个交易或者不包含, 交易发起者不能通过设置低额的gas price去虐待凌辱这个系统.

Storage, Memory and the Stack

The Ethereum Virtual Machine has three areas where it can store data: storage, memory and the stack.

evm有三个区域可以存储数据: 存储,内存以及 栈

Each account has a data area called storage, which is persistent between function calls and transactions. Storage is a key-value store that maps 256-bit words to 256-bit words. It is not possible to enumerate storage from within a contract, it is comparatively costly to read, and even more to initialise and modify storage. Because of this cost, you should minimize what you store in persistent storage to what the contract needs to run. Store data like derived calculations, caching, and aggregates outside of the contract. A contract can neither read nor write to any storage apart from its own.

每一个账户都有一个数据区域,称之为存储,这个区域永久性的存在于函数调用和事务之间. 存储是一个键值对,存储的是一个256bit的字符 key-value对.

在一个合约内部是不能去枚举所有的数据存储.  相比而已,读取是非常耗费gas费的, 而初始化和修改存储区的数据更昂贵.  由于这个花费的问题, 你应该最小化

你想存入到永久存储中的数据. 只将必要的数据放到合约中.  存储数据比如派生出的计算,缓存,以及聚合等尽量放在合约之外.

一个合约既不能读也不能写除自己之外其他合约的存储数据.

The second data area is called memory, of which a contract obtains a freshly cleared instance for each message call. Memory is linear and can be addressed at byte level, but reads are limited to a width of 256 bits, while writes can be either 8 bits or 256 bits wide. Memory is expanded by a word (256-bit), when accessing (either reading or writing) a previously untouched memory word (i.e. any offset within a word). At the time of expansion, the cost in gas must be paid. Memory is more costly the larger it grows (it scales quadratically). 内存区域是按照一个字(256位)进行扩展的, 当进行读写访问之前的一个为加仓的内存字(也就是位移长度是一个字256位),随着时间的延长,gas也必须是要支付的, 内存对于gas的消费是随着大小而增长的(指数级增长)

第二部分的数据区域我们称之为内存, 针对合约的每次消息的调用,都会获取一份干净新鲜的内存区域. 内存区域是是线性连贯的, 可以通过字节级别进行寻址到.

但是读取只能读256位比特宽的数据, 可以读8位,或者256位比特宽.

The EVM is not a register machine but a stack machine, so all computations are performed on a data area called the stack. It has a maximum size of 1024 elements and contains words of 256 bits. Access to the stack is limited to the top end in the following way: It is possible to copy one of the topmost 16 elements to the top of the stack or swap the topmost element with one of the 16 elements below it. All other operations take the topmost two (or one, or more, depending on the operation) elements from the stack and push the result onto the stack. Of course it is possible to move stack elements to storage or memory in order to get deeper access to the stack, but it is not possible to just access arbitrary elements deeper in the stack without first removing the top of the stack.

EVM不是一个注册机,而是一个栈机, 因此所有的计算是在数据区域进行的,我们称之为栈. 它有最大1024个元素,包含256位的字.

访问栈限制为访问最顶端. 通过如下方式. 可以复制栈最顶端16个元素中的一个到栈的最顶端,或者将最顶端元素的十六个元素和下方的进行交换.

所有其他的操作,从栈中取这最顶端的两个(或者一个或者更多,取决于操作)元素,然后将结果推送到栈中,当然也可以将栈中的元素存入到存储中或者内存中,用于访问更深处的栈, 但是不能实现随机访问栈中的深层元素,而不需要将第一个元素移除栈顶.

Instruction Set 指令集合

The instruction set of the EVM is kept minimal in order to avoid incorrect or inconsistent implementations which could cause consensus problems. All instructions operate on the basic data type, 256-bit words or on slices of memory (or other byte arrays). The usual arithmetic, bit, logical and comparison operations are present. Conditional and unconditional jumps are possible. Furthermore, contracts can access relevant properties of the current block like its number and timestamp.

For a complete list, please see the list of opcodes as part of the inline assembly documentation.

EVM的指令集保持着最小的状态,是为了避免不正确或者不一致的实现,从而导致共识问题. 所有的指令操作都是基于基本的数据类型. 256位的字或者内存中的一个片段(或者其他字节数组), 正常的算术,bit 逻辑和比较操作都是. 条件和无条件的跳跃是可能的. 此外 合约可以访问当前区块中的相关属性,比如块的编号和时间戳.

想看完整的指令列表,请查阅内联汇编文档的操作码部分.

Message Calls

Contracts can call other contracts or send Ether to non-contract accounts by the means of message calls. Message calls are similar to transactions, in that they have a source, a target, data payload, Ether, gas and return data. In fact, every transaction consists of a top-level message call which in turn can create further message calls.

消息调用

合约可以调用其他合约或者发送eth给其他非合约账户,通过消息调用的方式.  消息调用跟事务是非常类似的,在这个场景中,有源头账户,目标账户,数据载重,eth

gas费以及返回数据. 实际上,每一个事务都是有 顶级的消息调用构成,并随之反过来创建更远期的消息调用.

A contract can decide how much of its remaining gas should be sent with the inner message call and how much it wants to retain. If an out-of-gas exception happens in the inner call (or any other exception), this will be signaled by an error value put onto the stack. In this case, only the gas sent together with the call is used up. In Solidity, the calling contract causes a manual exception by default in such situations, so that exceptions “bubble up” the call stack.

一个合约可以决定多少留存的gas费应该通过内联消息调用的方式发送,以及他想保留多少. 如果gas费不足的异常发生在内联调用中(或者其他的异常情况),这个异常会通过

erro的方式推送到栈中. 在这种情况下,只有跟随调用的gas费被使用完. 在Solidity中, 刚才的那种情况下,正在调用的合约中会引发一个手动的异常,那就是调用栈沸腾异常.

As already said, the called contract (which can be the same as the caller) will receive a freshly cleared instance of memory and has access to the call payload - which will be provided in a separate area called the calldata. After it has finished execution, it can return data which will be stored at a location in the caller’s memory preallocated by the caller. All such calls are fully synchronous.

正如我们已经说过的那样,被调用的合约(同样的调用方的合约也一样)将会收到一个完全干净新鲜的内存实例,可以访问付费负载,合约提供了一个单独的数据,我们称之为调用数据. 当调用执行结束的时候, 会返回数据,这个返回数据被存储在调用方的预分配内存中某个地方. 所有的这些操作都是同步的.

Calls are limited to a depth of 1024, which means that for more complex operations, loops should be preferred over recursive calls. Furthermore, only 63/64th of the gas can be forwarded in a message call, which causes a depth limit of a little less than 1000 in practice.

调用方限制的深度是1024, 这也就意味着对于更加复杂的操作,循环调用会比递归调用好. 此外在消息调用中,只有63/64级的gas可以被转发,这就导致实际上,

可以有最多1000次调用深度.

Delegatecall and Libraries

委托调用和库

There exists a special variant of a message call, named delegatecall which is identical to a message call apart from the fact that the code at the target address is executed in the context (i.e. at the address) of the calling contract and msg.sender and msg.value do not change their values.

在消息调用中存在一种特殊的变种,我们称之为 代理调用,这种调用跟消息调用是完全相同的. 唯一的区别就是目标地址中的代码被执行是在调用合约的上下文中环境中(比如地址),以及 msg.sender 和msg.value 并没有变更它们的值.

This means that a contract can dynamically load code from a different address at runtime. Storage, current address and balance still refer to the calling contract, only the code is taken from the called address.

这也就意味着 合约可以在运行时从不同地址中动态加载. 存储区,当前地址,以及余额仍然指向的是调用的合约, 仅仅只是代码是从被调用的地址中取出来的.

This makes it possible to implement the “library” feature in Solidity: Reusable library code that can be applied to a contract’s storage, e.g. in order to implement a complex data structure.

这就可以让Solidity实现库一样的特性, 可以重复使用的代码库, 可以被应用在一个存储中,比如 为了实现一个复杂的数据结构.

Logs

It is possible to store data in a specially indexed data structure that maps all the way up to the block level. This feature called logs is used by Solidity in order to implement events. Contracts cannot access log data after it has been created, but they can be efficiently accessed from outside the blockchain. Since some part of the log data is stored in bloom filters, it is possible to search for this data in an efficient and cryptographically secure way, so network peers that do not download the whole blockchain (so-called “light clients”) can still find these logs.

可以将数据存储在一个专门索引的数据结构中,该结构一直映射到块级别。这个特性在Solidity中称为日志,用于实现事件.

合约在被创建之后就是不能够访问日志数据, 但是他们可以从区块链外部高效的访问到.  由于部分日志数据存储时采用的是布隆过滤器的方式,

因此可以非常高效的访问检索到这部分数据,并且通过密码加密的安全方式. 因此轻客户端网络节点不下载整个区块链(因此称为轻客户端),仍然可以找到这些日志.

Create

Contracts can even create other contracts using a special opcode (i.e. they do not simply call the zero address as a transaction would). The only difference between these create calls and normal message calls is that the payload data is executed and the result stored as code and the caller / creator receives the address of the new contract on the stack.

Deactivate and Self-destruct

The only way to remove code from the blockchain is when a contract at that address performs the selfdestruct operation. The remaining Ether stored at that address is sent to a designated target and then the storage and code is removed from the state. Removing the contract in theory sounds like a good idea, but it is potentially dangerous, as if someone sends Ether to removed contracts, the Ether is forever lost.

将代码从合约中删除的唯一方法就是一个合约调用自己的析构函数. 存储在当前地址上的eth将会被发送到预设的目标地址上,同时存储区以及代码从状态中移除.

将合约移除听起来是一个好的注意,但是潜藏着危险. 因为假设有人将eth发送到删除的合约中, eth将永远的丢失.

If you want to deactivate your contracts, you should instead disable them by changing some internal state which causes all functions to revert. This makes it impossible to use the contract, as it returns Ether immediately.

如果你想失效你的合约,你应该 改变内部的状态并且会导致所有的函数回滚从而使得当前合约失效. 这就使得这个合约不能使用,并且将eth立即返回.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容