以太坊是一种确定性但实际无界的状态机,有两个基本功能:全局可访问的单例状态和对状态进行更改的虚拟机。进一步说,以太坊是一个开源的、全球的去中心化计算架构,它执行被称为智能合约的程序,使用区块链来同步和存储系统的状态,使用称为ether的加密货币来计量和约束执行资源成本。
状态机状态机是有限状态自动机的简称,是现实事物运行规则抽象而成的一个数学模型。包含四大概念:状态、事件、动作、变换
区块链的组件
gossipgossip就是一个并行的图广度优先遍历算法。假设A得到某些信息,更新了自身的信息,A需要将信息告诉B、C等,然后B、C告诉其他的D、E、F、G,一直遍历。如果节点B收到A的消息,发现自己早就知道这个消息就直接忽略,从而可以防止图重复遍历。和路由器使用的路由表同步算法类似,只不过路由器还会维护每个路径的cost。gossip常用于维护集群的拓扑结构(路由器也是),被redis、consul使用。
gas以太坊无法预测合约是否会终止,于是通过gas来限制智能合约使用的资源。每一条指令都以gas为单位的成本,如果实际计算所消耗的gas超过了gaslimit,EVM将终止执行。gas是以太坊用于允许图灵完备计算的机制
从区块链到DApps以太坊从作为一种可用于各种用途的通用区块链开始,其愿景已经扩展为编程DApp到平台。DApp代表着比智能合约更广阔的视角。一个DApp至少是一个智能合约和一个web用户界面。进一步说,DApp是一个基于开放的、去中心化的、点对点基础架构服务的web应用程序
此外,DApp还常常包括其他去中心化组件:去中心化p2p存储协议和平台去中心化p2p消息传递和平台
DApp常写作DApps,D是拉丁字母,读作ETH
web3目前web2DApp的概念旨在将web引入web3,去中心化对等协议将进入web应用程序的方方面面
web3代表着web应用程序的新愿景和焦点:从集中拥有和管理的应用程序,到去中心化协议的应用程序。
Ethereum+web3js+JS库,会在浏览器中运行的js应用程序和以太坊区块链相连接。此外,web3.js库还提供了一个名为Swarm的P2P存储网络接口和一个成文Whisper的P2P消息传递服务。根据以上组件,开发人员可以使用完整的应用程序开发套件来构建web3DApp。
以太坊:ethereum以太坊货币:以太:ether:Ξ
账户外部所有账户(EOA):拥有私人密钥的账户,可以控制资金或对合约的访问合约账户:合约账户由以太坊记录,由EVM执行的软件程序的逻辑拥有和控制
以太坊客户端主要有六种语言编写Go:GethRust:parityC++:cpp-ethereumPython:pyethereumScala:mantisJava:harmony
轻量级客户端可连接现有网络,如自己的完整节点、公共区块链、公开或许可的测试网或本地私有区块链。实际上常用轻量级客户端(metamask)在所有不同节点选项之间切换。此外轻量级客户端常和钱包换用,轻量级客户端除了提供钱包的交易功能外还提供API。
mainnet&testnet
密码学是以太坊技术基础加密可以用来证明秘密的知识而不泄漏(数字签名),或验证数据的真实性(数字指纹)加密不是以太坊的重要组成部分,因为起通信和交易数据没有加密也不需要加密
简介
在EOA中,以太的所有权通过数字密钥、以太坊地址和数字签名建立
数学部分
公钥:64字节//046e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b83b5c38e5e2b0c8529d7fa3f64d46daa1ece2d9ac14cab9477d042c84c32ccd0私钥:32字节//f8f8a2f43c8376ccb0871305060d7b27b0554d2cc72bccf41b2705608452f315地址:20字节//0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9
如何判断正在使用那种哈希加密函数(FIPS-202还是Keccak-256)给一个预定输入,看输出判断常用空输入Keccak256("")=c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470SHA3("")=a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a
通过修改十六进制地址的大小写,EIP-55为以太坊地址提供了向后兼容的校验和通过修改地址中字母字符的大小写,我们可以传达一个校验和,用来保护地址的完整性,防止输入或读取错误。如果钱包不支持EIP-55校验和,会忽略大写的事实。但如果钱包支持EIP-55校验和,就可以验证它并以99.986%的准确度检测错误。原地址:0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9EIP-55混合大小写校验和:0x001d3F1ef827552Ae1114027BD3ECF1f086bA0F9
EIP-55计算方式简单来说先计算小写地址的哈希(不带0x)如果哈希的相应数字大于等于0x8,则地址的字母要大写Address:001d3f1ef827552ae1114027bd3ecf1f086ba0f9Hash:23a69c1653e4ebbb619b0b2cb8a9bad49892a8b9...EIP-55:001d3F1ef827552Ae1114027BD3ECF1f086bA0F9输入地址的时候只要输错一位,计算出来的哈希就会发生变化,导致大小写的位置完全对不上
交易是由EOA发起的签名消息,由以太坊网络传输并在以太坊区块链上记录。它是唯一可以触发状态更改或者导致合约在EVM中执行的东西。以太坊是一个全球的单实例状态机器,交易是唯一可以让状态机运动、改变状态的东西。即合约不会自动运行、以太坊不会自动运行,一切运行都始于交易
交易的基本结构交易的网络序列化是交易结构的唯一通用标准交易是一个序列化的二进制消息,其中包含以下数据:
跟踪nonce查询账户已确认交易数量的最新计数web3.eth.getTransactionCount("0x9e713963a92c02317a681b9bb3065a8249de124f")40最新计数为40,意味着下一个交易的nonce将是40。nonce有着确认机制,意味着按照顺序创建多个交易后,其中有一个交易未被开采,那么后面等所有交易将被卡住。如果出现两个nonce相同的交易(并发时出错),前面的将进行,后面的会被拒绝。
并发、交易、nonce在以太坊这种去中心化/分布式实时系统中,并发会突然出现。简单来说,并发是多个独立系统同时计算,这些可以在相同的的程序中(多线程)、同样的CPU中(多进程)或不同的计算机中(分布式)。而以太坊是一个允许(节点、客户端、DApps)并发多系统,但强制实施单一状态。
交易gasgasPrice&startPricegasPrice:每单位gas的汇率,1gas=?wei,1ether=10^18weistartPrice:本次交易愿意付出的gasgas是以太坊的燃料。gas不是ether,它是独立的虚拟货币,有相对于ether的汇率。gas与ether分离,以保护系统免受随着ether价值快速变化而产生的波动。
web3界面通过计算几个区块的中间价格来提供gasPrice建议truffle(mainnet)>web3.eth.getGasPrice(console.log)truffle(mainnet)>nullBigNumber{s:1,e:10,c:[10000000000]}
交易的接收者to交易的接受人由to指定,包含一个20个字节的以太坊地址,可以说EOA或合约。以太坊不会验证是否有这个地址,任何20个字节的值都是有效值。验证地址是否有效,应该在用户界面层级完成。如果发送到不存在的地址,ehter会燃烧。实际上也存在着一些专门用于燃烧ether的合约。
交易的价值和数据value&datavalue和data可以都有,可以都没有,可以只有一个只有value的交易是支付只有data的交易是调用没有value也没有data的交易是浪费gas
将value传给EOA或合约对于EOA,将把发送的余额添加到地址的余额中。如果地址之前没有被观测过,会创建地址并初始化余额。对于合约地址,会尝试调用data中指定的函数。如果没有data,EVM会调用目标合约的fallback函数,如果该函数是payable,将执行函数以确定下一步。合约可以通过在调用付款功能时立刻抛出异常或由条件来拒绝收款。如果付款成功,合约状态将更新,ether余额增加。
将数据传到EOA或合约一般如果交易包含data,大概率是发到合约上的。如果发送到EOA上,多数钱包会忽视data如果发送到合约上,data将被EVM认为是一个函数调用,调用指定的函数并将任何编码参数传递给该函数。发送给合约的data是一个十六进制的编码函数选择器:函数原型的Keccak256哈希的前4个字节。这使EVM能够明确地识别你希望调用的功能。函数的参数:根据EVM定义的各种基本类型的规则进行编码。
特殊交易:注册合约发送到零地址的,带有data但是没有value的交易,表示注册一个新的合约。合约注册交易的to字段包括地址0x0,该地址不代表EOA,也不代表合约,不会花费ether和启动交易,仅作为注册合约的目的。
特殊交易:燃烧燃烧地址0x000000000000000000000000000000000000dEaD
数字签名如何工作数字签名由两部分组成。第一部分是使用私钥从交易中创建签名,第二部分是允许任何人使用公钥来验证签名。
创建数字签名ECDSA中:Sig=F_sig(F_keccak256(m),k),其中:m是RLP编码的交易,k是签名私钥,F_sig是签名算法,Sig是产生的签名F_sig产生了一个由两个值组成的签名Sig,通常称为R,SSig=(R,S)被签名:交易(来自交易的哈希)签名密钥:EOA私钥签名结果:签名
验证签名验证签名必须有签名(R和S)和序列化交易和公钥(与创建签名的私钥对应)。验证签名代表着:只有生成此公钥的私钥的所有者才能在此交易上签名。如果签名对此消息有效,返回TRUE
※※※ECDSA数学--后续补上※※※
实践中的签名过程要在以太坊签署交易,发件人必须:
签名前缀v和公钥恢复从ECDSA签名中计算签名者公钥称为公钥恢复交易签名包含一个前缀值v,它告诉我么两个可能的R中哪一个是临时的公钥。(R和R'是公钥的两种可能性)如果v是偶数,R是正确值。如果v是奇数,R'是正确值
离线签名(为了安全)
交易广播以太坊网络使用“泛洪”路由协议。每个以太坊客户端,在_Peer-to-Peer(P2P)中作为_node,(理想情况下)构成_mesh_网络。没有网络节点是“特殊的”,它们都作为平等的对等体。我们将使用术语“节点”来指代连接并参与P2P网络的以太坊客户端。交易传播开始于创建(或从离线接收)签名交易的以太坊节点。交易被验证,然后传送到_直接_连接到始发节点的所有其他以太坊节点。平均而言,每个以太坊节点保持与至少13个其他节点的连接,称为_邻居_。每个邻居节点在收到交易后立即验证交易。如果他们同意这是有效的,他们会保存一份副本并将其传播给所有的邻居(除了它的邻居)。结果,交易从始发节点向外涟漪式地遍历网络,直到网络中的所有节点都拥有交易的副本。几秒钟内,以太坊交易就会传播到全球所有以太坊节点。从每个节点的角度来看,不可能辨别交易的起源。发送给我们节点的邻居可能是交易的发起者,或者可能从其邻居那里收到它。为了能够跟踪交易的起源或干扰传播,攻击者必须控制所有节点的相当大的百分比。这是P2P网络安全和隐私设计的一部分,尤其适用于区块链。
写入区块链虽然以太坊中的所有节点都是相同的对等节点,但其中一些节点由_矿工_操作,并将交易和数据块提供给_挖矿农场_,这些节点是具有高性能图形处理单元(GPU)的计算机。挖掘计算机将交易添加到候选块,并尝试查找使得候选块有效的_Proof-of-Work_。不深入太多细节,有效的交易最终将被包含在一个交易块中,并记录在以太坊区块链中。一旦开采成块,交易还通过修改账户余额(在简单付款的情况下)或通过调用改变其内部状态的合约来修改以太坊单例的状态。这些更改将与交易一起以交易_收据_receipt的形式记录,该交易也可能包含_事件_events。我们的交易已经完成了从创建到被EOA签署,传播以及最终采矿的旅程。它改变了单例的状态,并在区块链上留下了不可磨灭的印记。
预定义的全局变量和函数在EVM中执行合约时,它可以访问一组较小范围内的全局对象。这些包括block,msg和tx对象。另外,Solidity公开了许多EVM操作码作为预定义的Solidity功能。
调用交易/消息msg:msg对象是启动合约执行的交易(源自EOA)或消息(源自合约)。它包含许多有用的属性:msg.sender:我们已经使用过这个。它代表发起消息的地址。如果我们的合约是由EOA交易调用的,那么这是签署交易的地址。msg.value:与消息一起发送的以太值。msg.gasgasleft():这次交易携带的gas减去交易执行到现在的gas。它已经被弃用,并将被替换为Solidityv0.4.21中的gasleft()函数。msg.data:调用合约的消息中的数据。msg.sig:数据的前四个字节,它是函数选择器,可以让EVM明确的知道我们想调用的功能。每当合约调用另一个合约时,msg的所有属性的值都会发生变化,以反映新的调用者的信息。唯一的例外是在原始msg上下文中运行另一个合约/库的代码的delegatecall函数。
交易tx.gasprice:发起调用的交易中的gas价格。tx.origin:源自(EOA)的交易的完整调用堆栈。
地址对象任何地址(作为输入传递或从合约对象转换而来)都有一些属性和方法:address.balance:地址的余额,以wei为单位。例如,当前合约余额是address(this).balance。address.transfer(amount):将金额(wei)转移到该地址,并在发生任何错误时抛出异常。我们在Faucet示例中的msg.sender地址上使用了此函数,msg.sender.transfer()。address.send(amount):类似于前面的transfer,但是失败时不抛出异常,而是返回false。address.call():低级调用函数,可以用value,data构造任意消息。错误时返回false。address.delegatecall():低级调用函数,保持发起调用的合约的msg上下文,错误时返回false。
内置函数addmod,mulmod:模加法和乘法。例如,addmod(x,y,k)计算(x+y)%k。keccak256,sha256,sha3,ripemd160:用各种标准哈希算法计算哈希值的函数。ecrecover:从签名中恢复用于签署消息的地址。
合约定义
函数合约中定义了可有EOA交易或其他合约调用的函数(Faucet示例中有withdraw和fallback函数)定义函数的语法:functionFunctionName([parameters]){public|private|internal|external}[pure|constant|view|payable][modifiers][returns(
关键字public,private,internal,external)指定了函数的可见性:publicPublic是默认的,这些函数可以被其他合约,EOA交易或合约内部调用。在我们的Faucet示例中,这两个函数都被定义为public。external外部函数就像public一样,但除非使用关键字this作为前缀,否则它们不能从合约中调用。internal内部函数只能在合约内部"可见",不能被其他合约或EOA交易调用。他们可以被派生合约调用(继承的)。privateprivate函数与内部函数类似,但不能由派生的合约调用(继承的)。请记住,术语internal和private有些误导性。公共区块链中的任何函数或数据总是可见的,意味着任何人都可以看到代码或数据。以上关键字仅影响函数的调用方式和时机。
合约的构造和自毁(构造函数和析构函数)Solidityv.0.4.21,构造函数是一个名称与合约名称相匹配的函数合约的生命周期始于EOA或其他合约的创建交易。如果有一个构造函数,它将在相同的创建交易中调用,并可以在创建合约时初始化合约状态。constructor关键字,一般来说构造函数的函数名要与合约名字相同,但是可以使用constructor()来代替functioncontractName()避免了重命名合约带来的错误,而且更容易确定哪个函数是构造函数。
`//VersionofSoliditycompilerthisprogramwaswrittenforpragmasolidity^0.4.22;
//Ourfirstcontractisafaucet!contractFaucet{addressowner;//InitializeFaucetcontract:setownerconstructor(){owner=msg.sender;}`
合约生命周期的另一端是合约销毁contractdestruction合约被称为SELFDESTRUCT的特殊EVM操作码销毁。它曾经是SUICIDE,但由于该词的负面性,该名称已被弃用。在Solidity中,此操作码作为高级内置函数selfdestruct公开,该函数采用一个参数:地址以接收合约帐户中剩余的余额。看起来像这样:selfdestruct(addressrecipient);
//Contractdestructorfunctiondestroy()public{require(msg.sender==owner);selfdestruct(owner);}
合约继承继承合约为了附加功能,扩展基础合约,使我们实现模块化继承合约使用is关键字指定父合约支持多继承contractChildisParent1,Parent2{}
错误处理assert、require、revert如果合约出现错误,所有的状态变化都会恢复,除了已花费的gas(这表明交易是原子性的,要么完成,要么对状态没有影响)。
事件Events
合约调用(call、send、delegatecall、callcode)调用其他合约:
Gas控制gas是智能合约编程中一定要考虑的因素gas是限制以太坊允许交易损耗大最大量的资源,如果计算过程中超过了gas限制则:
安全
设计模式
部署智能合约
在区块链上测试在geth终端输入eth.getTransactionReceipt(txhash);可用于获得在txhash处的合约地址。eth.getCode(contractaddress)获取部署在contractaddress的合约代码。这可以用来验证正确的部署。eth.getPastLogs(options)获取位于地址的合约的完整日志,在选项中指定。这有助于查看合约调用的历史记录。eth.getStorageAt(address,position)获取位于address的存储,并使用position的偏移量显示该合约中存储的数据。
框架
nodejsnpmnvm(node版本管理器)创建了一个包含DApp支持的Node.js版本的隐藏文件.nvmrc,这样开发人员只需要在项目运行nvminstall就会自动安装并切换该版本的nvm继续使用npm-g安装truffle
使用一个预先构建的模版上的DAppTruffleunbox
创建Truffle项目命名项目文件Faucet初始化Truffle,目录结构:.├──contracts│└──Migrations.sol├──migrations│└──1_initial_migration.js├──test└──truffle-config.js安装js支持包安装truffle依赖
配置Truffletruffle-config.js设置了一个默认的以太坊节点,该网络假定了我们正在运行以太坊客户端,既可以作为完整节点,也可以作为轻量型节点。truffle-config.js指示了truffle与端口8545上的本地节点通过RPC进行通信。truffle将使用本地节点连接任何以太网和测试网络,本地节点也会有钱包功能。使用truffle部署合约在contracts子目录中粘贴合约。还可以执行trufflecompile编译合约。trufflemigrations理解部署脚本truffle通过migrations.sol来跟踪哪些合约已经部署。如果一个项目拥有数十个合约和复杂的依赖关系,就不必为了尚未更改的合约支付gas。migrations目录里有一个脚本1_initial_migration.js,它会部署Migrations.solinclude::code/truffle/Faucet/migrations/1_initial_migration.jsvarMigrations=artifacts.require("./Migrations.sol");module.exports=function(deployer){deployer.deploy(Migrations);};
我们需要第二个migrations脚本来部署Faucets.sol,可命名为2_deploy_contracts.js,只需要对1_initial_migration.js稍作修改。include::code/truffle/Faucet/migrations/2_deploy_contracts.jsvarFaucet=artifacts.require("./Faucet.sol");module.exports=function(deployer){deployer.deploy(Faucet);};准备好了后使用trufflemigrate来部署合约
zeppelin_oszeppelin_os是一款开源的分布式工具和服务平台,位于EVM之上,可以安全的开发和管理智能合约应用程序。与OpenZeppelin的代码每次都需要重新部署每个应用程序不同,zeppelin_os的代码处于链上。
what'stoken区块链中,Token是一种抽象概念,可以被拥有,代表资产、货币或者访问权。
怎么使用TokenToken最明显的用途是数字私人货币,但也可以参与编程,提供许多功能。比如传达投票权、访问权和资源所有权。
很多项目的发行都使用Token,用于为项目的服务支付。一个新项目的Token分为实用Token(用于支付服务、应用程序、资源)和权益Token(代表初创团队股票的Token)如果Token的应用环境非常下载,那么Token只有“微不足道的价值”。采用Token是因为不使用Token就无法工作,而不是为了快速筹集资金。
ERC必须的函数和事件:
ERC20可选函数
在Solidity中定义ERC20接口
contractERC20{functiontotalSupply()constantreturns(uinttheTotalSupply);functionbalanceOf(address_owner)constantreturns(uintbalance);functiontransfer(address_to,uint_value)returns(boolsuccess);functiontransferFrom(address_from,address_to,uint_value)returns(boolsuccess);functionapprove(address_spender,uint_value)returns(boolsuccess);functionallowance(address_owner,address_spender)constantreturns(uintremaining);eventTransfer(addressindexed_from,addressindexed_to,uint_value);eventApproval(addressindexed_owner,addressindexed_spender,uint_value);}ERC20的数据结构任何ERC20实现,它将包含两个数据结构,一个用于追踪余额,另一个用于追踪配额(allowances)。在Solidity中,它们使用datamapping(数据映射)实现。第一个datamapping是允许Token合约跟踪谁拥有Token,mapping(address=>uint256)balances;第二个datamapping是配额,允许花钱者从所有者的账户中花费特定金额,并通过二维映射追踪配额(从所有者地址映射到一个花费者地址和配额金额)mapping(address=>mapping(address=>uint256))publicallowed;
ERC20的工作流程:transfer和approve&transerFrom
假设Alice希望允许AliceICO合同将所有AliceCoinToken的50%卖给像Bob和Charlie这样的买方。首先,Alice发布AliceCoinERC20合同,将所有AliceCoin发放到她自己的地址。然后,Alice发布可以以ether出售Token的AliceICO合同。接下来,Alice启动approve&transferFrom工作流程。她向AliceCoin发送一个交易,调用approve,参数是AliceICO的地址和totalSupply的50%。这将触发Approval事件。现在,AliceICO合同可以出售AliceCoin了。
当AliceICO从Bob那收到ether,它需要发送一些AliceCoin给Bob作为回报。在AliceICO合约内是AliceCoin和ether之间的汇率。Alice在创建AliceICO时设置的汇率决定了Bob将根据他发送给AliceICO的ether数量能得到多少Token。当AliceICO调用AliceCointransferFrom函数时,它将Alice的地址设置为发送者,将Bob的地址设置为接收者,并使用汇率来确定将在“value”字段中将多少AliceCoinToken传送给Bob。AliceCoin合同将余额从Alice的地址转移到Bob的地址并触发Transfer事件。只要不超过Alice设定的审批限制,AliceICO合同可以调用transferFrom无限次数。AliceICO合同可以通过调用allowance函数来跟踪它能卖出多少AliceCoinToken。
实现ERC20EIP20中提到了两种实现:
发布自己的ERC20
ERC20Token的问题ERC20Token暴露了Token和ether之间的细微差别。
ERC223一种Token合同接口标准通过检测目的地地址是否是合同来解决无意中将Token转移到合同的问题。
ERC721ERC721提案是不可互换的Tokens标准,也称为契据/deeds。前面的所有Token标准是可互换的Token。
Token标准
DAppp2p使互联网用户连接到了一起USENET是第一个p2p架构的分布式消息传递系统Napster是一款音乐和文件共享应用,是完全点对点网络运动转化为BitTorrent的开始,参与用户完全独立于物理网络,无需遵守任何管理机构DApp不属于单个服务器,而是将整个栈建在p2p网络上以分布式进行存储和操作。一个DApp包括前端、后端和数据存储DApp相比传统集中式架构有如下优点:
DApp的组件
DApp框架
EVM能保证相同的操作返回相同的输出,无论运行在什么地方。这保证了以太坊的安全,但阻止了智能合约检索和处理脱链数据,Oracles能解决这个问题。
oracles的主要功能:回应去中心化应用的查询、解析查询、检查是否符合付款和数据权限、从脱链源中检索数据、在交易中签署数据、向网络广播交易、进一步安排交易
订阅模式请求响应模式:常见于客户端-服务器体系发布订阅模式:例如:发布者是oracles,不直接向用户发布信息,而是将发布的信息分到不同的类中。订阅者能够订阅多个类。此时orcales可以将利率写道自己的内部存储,当且仅当它发生变化时,多个DApp才从oracles中读取它,以减少对网络带宽的影响
数据认证数据认证的任务是保证脱链方法返回的数据完整安全不被篡改。数据认证常用的两种方法:
计算oracleoracles可用于执行任意计算,这在以太坊的环境中特别有用。
去中心化的oracle集中式oracle系统虽然满足了许多应用,但也确实是以太网网络的中心故障点。ChainLink提出了一个去中心化的oracle网络,包括三个关键的智能合约和数据提供商的脱链注册:
Solidity中的Oracle客户端接口此处复杂,先学Solidity
以太坊用于衡量执行一组动作所需计算量的单位,交易或者合约执行都需要一定量的gas。gas具有双重作用:
停机问题交易过载
支付gasgas有价格,但不能被拥有和花费,仅存在于EVM内部,作为工作量的计数。收取ether--->转化为gas--->转回ether
gas价格、成本限制、耗尽交易前发起方需要指定gaslimit和gaspricegaslimit多了,发起方收到退款gaslimit少了,交易失败,gas不退回
估算gas通过假装交易已经被包含在区块链中来估算gas
varresult=web3.eth.estimateGas({to:"0xc4abd0339eb8d57087278718986382264244252f",data:"0xc6888fa10000000000000000000000000000000000000000000000000000000000000003"});console.log(result);//"0x0000000000000000000000000000000000000000000000000000000000000015"gas价格和交易优先顺序gasprice设置的高一般回处理的更快
区块gas限制Blockgaslimit是区块中允许的最大gas量,锁定了区块中可以容纳的交易数量18年,区块gas限制在500w左右,可以容纳约238个交易,每个交易消耗21000gas矿工决定了区块gas限制是什么,矿工可以对gas限制进行投票来扩容
gas退款以太坊通过退还高达一半的gas费用来鼓励删除存储的变量EVM中有2个负的gas操作:清理合约是-24,000(SELFDESTRUCT)清理存储为-15,000(SSTORE[x]=0)
gasTokengasToken是一种ERC20的Token,允许任何人在gas价格低时存储gas,在gas价格高时使用gas
租金以太坊社区建议向智能合约收取“租金”来保持活力不支付租金时,合约将被睡眠,简单的读取操作也无法进行,需要通过缴纳租金和提交merkle证据来唤醒睡眠的合约。
EVM是实际处理内部状态和计算的协议部分,实际来看,EVM是包含数百万个对象的大型去中心化虚拟机
EVM机器语言EVM的机器语言分为特定指令集合:算术、逻辑和比较、控制流、系统调用、堆栈操作、存储器操作、管理账户、gas和区块信息
状态就像CPU跟踪执行过程一样,EVM必须跟踪各种组件的状态以支持以太坊交易。以太坊也被描述为基于状态的虚拟机,包含以下组件
状态转换计算函数
.sol编译为EVM字节码solc命令solc--help使用--opcode命令编译后生成.opcode机器语言操作码文件使用--asm命令编译后生成一个.evm的机器语言说明文件使用--bin命令编译后生成一个字节码文件使用--bin-runtime编译后生成一个运行时字节码文件
执行EVM字节码
反汇编字节码
共识度量共识度量是可测量的数据,区块链网络的节点必须在该数据上达成一致。
每当新块添加到链中时,每个网络节点会测量并批准一致性度量。
作为共识度量的结果,区块链充当了从一个确定可验证的事实延伸到下一个事实的真理链。基于共识度量,区块链协议的节点变成迷你公证人(mini-notaries),它可以立刻从真实的节点中分辨出区块链的错误副本,并报告全网络,以便组织提交虚假信息的区块来欺骗网络。
基于一致性度量,区块链不仅建立了完整性,并保持长期不变。共识度量有多种,最重要的两种是基于工作量的度量和基于风险的度量。
POW基于POW,度量间建立了共识:因为他们使用协议将计算机设置为查找难题的答案,即找到适合网络参数的散列的难题要求节点提交处理能力并使用电力与其他节点竞争以提出有效的哈希。
基于风险的度量基于风险的度量基于共识:选择创建无效区块的每个人都会失去比通过创建有效区块获得的更多的东西。这种度量是通过链内数据的共识创造的,而不是pow那种链外共识。
以太坊共识EthashEthash是pow,依赖于数据集的初始纪元产生,该数据集约1GB,是有向无环图(DAG)。
Polkadot简介Polkadot是一种链间区块链协议,包括与权益证明(PoS)链的整合,允许Parachain在没有内部共识的情况下获得共识。
智能合约漏洞的基本类别:
Vtper是一种面向智能合约的实验性编程语言,面向EVM。Vyper致力于通过简化代码并使其对人类可读而提供卓越的审计能力。Vyper的一个原则是让开发人员几乎不可能编写误导性代码。
与Solidity比较
VyperVyper打开了新的大门,偏离了传统的面向对象编程(OOP)
在线代码编辑器Vyper拥有自己的在线代码编辑器
命令行运行扩展名为.v.py,安装Vyper后,可以运行命令来编译和提供字节码
读写数据智能合约可以将数据写入两个地方:以太坊的全球状态查找树或以太坊的链数据。
虽然智能合约可以写入以太坊的链数据(通过日志事件),但智能合约无法读取他们创建的链上日志事件。但可以在公共链上由轻客户端发现和读取日志。
操作码(OPCODES)合约一般用Solidity或Vyper等高级语言编写,编译器负责获取高级代码并创建他的低级解释,然后在EVM上运行。编译器可以提取代码的最低表示(在EVM执行前)是操作码。这种情况下需要高级语言的每个实现来提供适当的编译机制以允许将高级代码编译到通用预定义的EVM操作码中。Vyper实现了以太坊的分片操作码
EIPsEIP代表以太坊改进提案。EIP是一个设计文档,为以太坊社区提供信息,或描述以太坊或其过程或环境的新功能。EIP应提供该功能的简明技术规范和该功能的基本原理。EIP作者负责在社区内建立共识并记录不同意见。
ERCsERC代表以太坊征求建议。如果EIP被接受,它将成为ERC的一部分
多数的硬分叉作为路线图的一部分,包含社区普遍认同的更新,这被称为共识。但也有一些硬分叉不是共识,这会导致多个不同的区块链,例如以太坊/以太坊经典。
以太坊经典(ETC)2016年7月20日,在192w的区块高度上,以太坊通过硬分叉引入了改变,退还了360w的ether,这些ether来自名为TheDAO的合约。
TheDAODAO由Slock.lt创建,被视为基于社区,为项目提供资金的一种方式。核心思想是提交提案,管理者管理提案,资金从以太坊的投资者筹集,如果项目成功,投资者将会获得收益。DAO是以太坊token的一个实验。
重入bug(Re-Entrancy)DAO攻击者从DAO中吸取了360w个ether。RHG志愿者开始用相同的漏洞提取剩余的资金,并计划退还社区,保护了社区的大部分ether。