solidity之Storage与Memory

在solidity中,两个地方存储变量,分别是storage和memory。Storage变量是永久存在区块链中的变量,而memory变量则是临时的,当外部函数对某合约调用完成时memory即被移除。 但其实大多数时候你都用不到这些关键字,默认情况下 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....

April 26, 2021 · 1 min · Rufus

Solidity之数组

在最近看到的Solidity语言里面的数组的定义和之前学的稍有不同,记录一下。 下面是在单个合约里的情形,这些数组只能在test合约中被访问。 pragma solidity ^0.4.19; contract test { // 固定长度为2的静态数组: uint[2] fixedArray; // 固定长度为5的string类型的静态数组: string[5] stringArray; // 动态数组,长度不固定,可以动态添加元素: uint[] dynamicArray; } 然后是公共数组,这个数组可以被test合约之外的其他合约读取 contract test { Person[] public people; } 另外,solidity里的数组有一个push方法,效果和python中的append类似 uint[] public a; a.push(1); a.push(2); a.push(3); // 此时a=[1, 2, 3]

April 26, 2021 · 1 min · Rufus

最长链的选择

(本文转载,自己做了少许修改) 比特币没有中心机构,几乎所有的完整节点都有一份公共总帐本,那么大家如何达成共识:确认哪一份才是公认权威的总账本呢? 为什么要遵守协议 这其实是一个经济问题,在经济活动中的每个人都是自私自利的,追求的是利益的最大化,一个节点工作量只有在其他的节点认同其是有效的(打包的新区块,其他的节点只有验证通过才会加入到区块链中,并在网络上传播),才能够过得收益, 而只有遵守规则才会得到其他的节点认同。 因此,基于逐利,节点就会自发的遵守协议。共识就是数以万计的独立节点遵守了简单的规则(通过异步交互)自发形成的。 共识:共同遵守的协议规范 去中心化共识 在工作量证明一篇,我们了解通过工作量证明来竞争记账,权威的总帐本是怎么达到共识的,没有完全说清楚,今天补上,实际上,比特币的共识由所有节点的4个独立过程相互作用而产生: 每个节点(挖矿节点)依据标准对每个交易进行独立验证 挖矿节点通过完成工作量证明,将交易记录独立打包进新区块 每个节点独立的对新区块进行校验并组装进区块链 每个节点对区块链进行独立选择,在工作量证明机制下选择累计工作量最大的区块链 共识最终目的是保证比特币不停的在工作量最大的区块链上运转,工作量最大的区块链就是权威的公共总帐本。 第1 2 3步在比特币如何挖矿-工作量证明一篇有提到过,下面着重讲第4步。 最长链的选择 先来一个定义,把累计了最多难度的区块链。在一般情况下,也是包含最多区块的那个链称为主链 每一个(挖矿)节点总是选择并尝试延长主链。 分叉 当有两名矿工在几乎在相同的时间内,各自都算得了工作量证明解,便立即传播自己的“获胜”区块到网络中,先是传播给邻近的节点而后传播到整个网络。每个收到有效区块的节点都会将其并入并延长区块链。 当这个两个区块传播时,一些节点首先收到#3458A, 一些节点首先收到#3458B,这两个候选区块(通常这两个候选区块会包含几乎相同的交易)都是主链的延伸,分叉就会产生,这时分叉出有竞争关系的两条链,如图: 两个块都收到的节点,会把其中有更多工作量的一条会继续作为主链,另一条作为备用链保存(保存是因为备用链将来可能会超过主链难度称为新主链)。 分叉解决 收到#3458A的(挖矿)节点,会立刻以这个区块为父区块来产生新的候选区块,并尝试寻找这个候选区块的工作量证明解。同样地,接受#3458B区块的节点会以这个区块为链的顶点开始生成新块,延长这个链(下面称为B链)。 这时总会有一方抢先发现工作量证明解并将其传播出去,假设以#3458B为父区块的工作量证明首先解出,如图: 当原本以#3458A为父区块求解的节点在收到#3458B, #3459B之后,会立刻将B链作为主链(因为#3458A为顶点的链已经不是最长链了)继续挖矿。 节点也有可能先收到#3459B,再收到#3458B,收到#3459B时,会被认为是“孤块“(因为还找不到#3459B的父块#3458B)保存在孤块池中,一旦收到父块#3458B时,节点就会将孤块从孤块池中取出,并且连接到它的父区块,让它作为区块链的一部分。 比特币将区块间隔设计为10分钟,是在更快速的交易确认和更低的分叉概率间作出的妥协。更短的区块产生间隔会让交易确认更快地完成,也会导致更加频繁地区块链分叉。与之相对地,长的间隔会减少分叉数量,却会导致更长的确认时间。 转载资料 区块链记账原理

April 21, 2021 · 1 min · Rufus

比特币所有权及隐私问题-非对称加密应用

(本文转载,如有侵权,请联系博主QQ删除) 比特币系统是如何确定某个账户的比特币是属于谁的?谁可以支付这个账户比特币? 如果你对这个问题还不是很明白,那就一起来看看吧。 先说说银行系统 我们先来回顾下现实的银行系统: 首先我们需要把我们的个人信息(如身份证)给银行,银行给我们开立相对应的账户,银行在开户的时候确立了对账户的所有权。 进行支付的时候,银行对交易双方完成转账(银行在开户的时候已经知道我们对应的账户)。 同时银行会对账户信息进行保密(这点其实不能保证)。 匿名账本 那么比特币如何在没有第三方银行的参与下,在确保隐私的同时如何确定账户所有权的呢? 实际上比特币的账户是用地址来表示,账本上不显示个人信息,转账是把比特币从一个地址转移到另一个地址。 转账记录如这样: { "付款地址":"2A39CBa2390FDe" "收款地址":"AAC9CBa239aFcc" "金额":"0.2btc" } 接下来问题就变为了 谁有权用某个地址进行付款。 支付和所有权 实际是同一个问题,如果此比特币只有我可以用来支付,那么说明我拥有所有权 地址与私钥 比特币的解决方案是,谁拥有某个地址的私钥(如果完全没有加密概念的人,可以简单的把私钥当作密码),谁就能用这个地址进行支付。(所以私钥一定保管好,如果私钥泄漏,比特币就可能丢失) 比特币地址和私钥是一个非对称的关系,私钥经过一系列运算(其中有两次Hash)之后,可以得到地址, 但是无法从地址反推得到私钥。 地址: 2A39CBa2390FDe 私钥: sdgHsdniNIhdsgaKIhkgnakgaihNKHIskdgal Hash(Hash(fun(sdgHsdniNIhdsgaKIhkgnakgaihNKHIskdgal))) -> 2A39CBa2390FDe 银行系统银行账号和密码是完全独立的,无法互相推导,转出时需要同时验证账号和密码 还是上面交易的例子: { "付款地址":"2A39CBa2390FDe", "收款地址":"AAC9CBa239aFcc", "金额":"0.2btc" } 只有拥有地址2A39CBa2390FDe的私钥才能进行支付。 非对称加密技术 这个时候问题就变为了,如何证明你拥有某个地址的私钥(在不泄漏私钥的情况下)。 对交易信息进行签名 实际在签名之前,会先对交易信息进行Hash运算得到摘要信息,然后对摘要信息进行签名。过程大概是这样: 1.对交易进行hash, 得到一个摘要信息(Hash值) hash(' {"付款地址":"2A39CBa2390FDe", "收款地址":"AAC9CBa239aFcc", "金额":"0.2btc" }') -> 8aDB23CDEA6 2.用私钥对交易摘要进行签名(付款方在安全的环境下进行,以避免私钥泄密), 用代码表示大概是这样。 #参数1为交易摘要 #参数2为私钥 #返回签名信息 sign("8aDB23CDEA6", "J78sknJhidhLIqdngalket") -> "3cdferdadgadg" 广播 在签名运算之后,付款节点就开始在全网进行广播:我支付了0....

April 21, 2021 · 1 min · Rufus

区块链记账方法

(本文转载,自己做了少许修改) 原来是hash函数的妙用 之前整了整hash,现在来看看它在区块链交易中的应用。假设有一个账页序号为0的账页交易记录如下: 账号 入账 出账 余额 备注说明 王二 100 190 收到xxx货款 张三 100 30 xxxx 李四 120 90 170 xxxx 假设记账时间为:2017-10-22 10:22:02 区块链在记账是会把账页信息(包含序号、记账时间、交易记录)作为原始信息进行Hash, 得到一个Hash值,如:787635ACD, 用函数表示为: Hash(序号0、记账时间、交易记录) = 787635ACD 账页信息和Hash值组合在一起就构成了第一个区块。(好像又叫创世区块,反正就是第一个块,不用记上一个块的hash值) 比特币系统里约10分钟记一次账,即每个区块生成时间大概间隔10分钟 在记第2个账页的时候,会把上一个块的Hash值和当前的账页信息一起作为原始信息进行Hash,即: Hash(上一个Hash值、序号1、记账时间、交易记录) = 456635BCD 这样第2个区块不仅包含了本账页信息,还间接的包含了第一个区块的信息。依次按照此方法继续记账,则最新的区块总是间接包含了所有之前的账页信息。 所有这些区块组合起来就形成了区块链,这样的区块链就构成了一个便于验证(只要验证最后一个区块的Hash值就相当于验证了整个账本),不可更改(任何一个交易信息的更改,会让所有之后的区块的Hash值发生变化,这样在验证时就无法通过)的总账本。 转载资料 区块链记账原理

April 21, 2021 · 1 min · Rufus