区块链常见问题

1:以太坊的共识算法

在以太坊中,默认使用ethash(pow)共识算法进行网络正确性的保障,这种共识算法采用的是工作量证明的机制,也就是我们所熟知的“挖矿”。
在使用pow算法一段时间之后产生了一系列问题,大家把目光转向了casper(POS)共识算法,产生了共识算法Clique,这种算法的原理十分简单,即网络中的每一个区块是由某一个认证节点进行认证的,其他节点仅需要验证认证信息来判断该区块是否合法。

2:POS以及拜占庭算法,共识算法研究

POS:POS就是“股权证明”,Proof of stake,即直接证明你持有的份额。除了混合性的PPC之外,真正的POS币是没有挖矿过程的,也就是在创世区块内就写明了股权证明,之后的股权证明只能转让,不能挖矿。
也称股权证明,类似于财产储存在银行,这种模式会根据你持有数字货币的量和时间,分配给你相应的利息。简单来说,就是一个根据你持有货币的量和时间,给你发利息的一个制度,在股权证明POS模式下,有一个名词叫币龄,每个币每天产生1币龄,比如你持有100个币,总共持有了30天,那么,此时你的币龄就为3000,这个时候,如果你发现了一个POS区块,你的币龄就会被清空为0。你每被清空365币龄,你将会从区块中获得0.05个币的利息(假定利息可理解为年利率5%),那么在这个案例中,利息 = 3000 * 5% / 365 = 0.41个币,这下就很有意思了,持币有利息。
拜占庭算法:
拜占庭(BFT)是一类分布式计算领域的容错技术,拜占庭容错来源于拜占庭将军问题,拜占庭将军问题是Leslie Lamport(2013年的图灵讲得主)用来为描述分布式系统一致性问题(Distributed Consensus)在论文中抽象出来一个著名的例子。
• Lamport 对拜占庭将军的问题的研究表明,当 n > 3m 时,即叛徒的个数 m 小于将军总数的 n 的 1/3 时,通过口头同步通信(假设通信是可靠的),可以构造同时满足“一致性”和“正确性”的解决方法,即将军们可以达成一致的命令
• 安全性:任何已经完成的请求都不会被更改,它可以在以后请求看到。在区块链系统中,可以理解为,已经生成的账本不可篡改,并且可以被节点随时查看。
活性:可以接受并且执行非拜占庭客户端的请求,不会被任何因素影响而导致非拜占庭客户端的请求不能执行。在区块链系统中,可以理解为,系统需要持续生成区块,为用户记账,这主要靠挖矿的激励机制来保证。

3、智能合约Gas计算

交易消耗的gas数量(gasUsed)与交易中单位gas的价格(gasPrice)的积(用以太币计算)
交易费 = gasUsed * gasPrice

4、回退函数

一个合约只能有一个回退函数,无参无返回值,为了接受ether,需要有payable标识,当调用的函数名错误或有ether交易时会调用回退函数

五、send函数附属的gas,transfer函数

1.使用call调用函数的时候,可以附加以太币和gas,分别用.value()和.gas()表示。
2.直接使用函数名称和使用bytes4和keccak算法调用函数本质上是一样的,都可以附加以太币和gas。
3.直接调用address.call()函数不带任何参数,相当于调用了一个不存在的函数,会调用对应的回退函数。如果有附加的value,则回退函数必须添加payable关键字,否则执行失败。
4.call函数的返回值为 bool;

send()发送调用:
1.如果我们要在合约中通过send()函数接收,就必须定义fallback函数,否则会抛出异常;
2.fallback函数必须增加payable关键字,否则send()执行结果将会始终为false;
3.调用发送函数的函数不能推荐view和constant修饰,否则发送失败;

transfer(uint256 amount):
发送给定数量的ether到某个地址,以wei为单位。失败时抛出异常。

六、智能合约安全接触过哪些

1.重入漏洞
当以太坊智能合约将Ether发送给未知地址(地址来源于输入或是调用者)时,可能会发生此攻击。
攻击者可以在地址对应合约的Fallback函数中,构建一段恶意代码。当易受攻击的合约将Ether发送给攻击者构建的恶意合约地址时,将执行Fallback函数,执行恶意代码。恶意代码可以是重新进入易受攻击的合约的相关代码,这样攻击者可以重新进入易受攻击合约,执行一些开发人员不希望执行的合约逻辑
*解决方式:
1.在将Ether发送给外部合约时使用内置的transfer() 函数。transfer转账功能只发送2300 gas不足以使目的地址/合约调用另- -份合约(即重入发送合约)。
2.确保所有改变状态变量的逻辑发生在Ether被发送出合约(或任何外部调用)之前。
3.引入互斥锁。也就是说,要添加一个在代码执行过程中锁定合约的状态变量,阻止重入调用。
2、算法溢出漏洞
以太坊虚拟机(EVM)为整数指定固定大小的数据类型。这意味着一个整型变量只能有一定范围的数字表示。例如,一个uint8,只能存储在范围[O, 255]的数字。试图存储256到一个uint8将变成0。不加注意的话,只要没有检查用户输入又执行计算,导致数字超出存储它们的数据类型允许的范围,Solidity中的变量就可以被用来组织攻击。当执行操作需要固定大小的变量来存储超出变量数据类型范围的数字(或数据)时,会发生数据上溢/下溢。

*解决方式:防止溢出漏洞的(当前)常规技术是使用或建立取代标准数学运算符的数学库;加法,减法和乘法(除法被排除在外,因为它不会导致上溢/下溢,并且EVM除以0时会丢出错误)。
0ppenZepplin在构建和审计Ethereum 社区可以利用的安全库方面
做得非常出色。特别是,他们的SafeMath 是一个用来避免.上溢/下溢漏洞的参考或库。

3、可见性漏洞
函数的可见性默认是public。因此,不指定任何可见性的函数就可以由用户在外部调用。当开发人员错误地忽略应该是私有的功能(或只能在合约本身内调用)的可见性说明符时,问题就出现了。
*解决方式:总是指定合约中所有功能的可见性、即便这些函数的可见性本就有意设计成public,这是一种很好的做法。最近版本的Solidity 将在编译过程中为没有明确设置可见性的函数显示警告,以鼓励这种做法。
*解决方式:总是指定合约中所有功能的可见性、即便这些函数的可见性本就有意设计成public,这是一种很好的做法。最近版本的Solidity 将在编译过程中为没有明确设置可见性的函数显示警告,以鼓励这种做法。

4、条件竞争/抢先提交
与大多数区块链一样,以太坊节点汇集交易并将其打包成块。一旦矿工获得了共识机制(目前以太坊上实行的是ETHASH 工作量证明算法)的一个解,这些交易就被认为是有效的。挖出该区块的矿工同时也选择将交易池中的哪些交易包含在该区块中,一般来说是根据交易的gasPr ice来排序。在这里有一个潜在的攻击媒介。攻击者可以监测交易池,看看其,中是否存在问题的解决方案(如下合约所示)、修改或撤销攻击者的权限的交易或攻击者不想要的合约状态变更然后攻击者可以从该中获取数据并创建一个gasPrice 更高的交易,(让自己的交易) 抢在原始交易之前被打包到一个区块中。
*解决方式:可以采用的一种方法是在合约中创建逻辑,设置gasPrice的上限,可以防止用户增加 gasPrice 并因超出上限而获得优先的交易排序。这种预防措施只能缓解任意用户。在这种情况下,旷工仍然可以攻击合约,因为无论Gas价格如何,他们都可以安排包含在他们的块中的交易。
一个更强大的方法是尽可能使用 commit-reveal 方案。这种方案规 定用户使用隐藏信息(通常是哈希值)发送交易。在交易已包含在块中后, 用户将发送一个交易来显示已发送的数据(reveal 阶段)。这种方法可 以防止矿工和用户从事抢先交易,因为他们无法确定交易的内容。然而, 这种方法不能隐藏交易价值(在某些情况下,这是需要隐藏的有价值的信 息)。ENS 智能合约允许用户发送交易,其 commit 数据包括他们愿意花 费的金额。用户可以发送任意值的交易。在 reveal 阶段,用户可以取出 交易中发送的金额与他们愿意花费的金额之间的差额。

谷歌给出了解决方案:https://docs.google.com/document/d/ 1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit,大家翻墙查看 即可。

7、众筹合约,发币合约

发币合约:要求我们在实现代币的时候必须要遵守的协议,如指定代币名称、总量、实现代币交易函数等,只有支持了协议才能被以太坊钱包支持。
众筹合约:众筹就是我需要做一件事需要钱,我就把我的想法告诉大家,看看大家有没有兴趣投钱,在规定的时间内投够那些钱,到时候大家都是原始股东,如果在规定的时间内没有幕到那么多钱,然后就把那些钱退给大家。为了解决信任问题运用区块链技术,借助于智能合约。可以实现当募资完成时,募资款自动打到指定账户,募资未完成时,自动退还到各自的账户。这就不用依靠第三方信用担保了。

8、事件使用

事件使用:事件强调功能,一种行为;事件发生后被记录到区块链上成为日志。事件可以用来做操作记录,存储日志。
在solidity中,使用event关键字来定义一个事件,并且事件在合约中可以被继承。

9、内存区域如何划分

storage 会永久保存合约状态变量,永久存贮在区块链中,开销最大
memory 仅保存临时变量,函数调用之后释放,开销很小 stack 保存很小的局部变量,几乎免费使用,但有数量限制。

10、library(库)

库与合约类似,它也部署在一个指定的地址上,然后通过EVM的特性DELEGATECALL来复用代码。
(1)如果一个库里只包含内部函数或结构体或枚举,则不需要部署库,因为因为库合约是一个独立的代码,它仅可以访问主调合约明确提供的状态变量。
(2)无状态变量,不能继承或被继承,不能接收以太币,不能销毁一个库。不会修改状态变量库函数只能通过直接调用(不用DELEGATECALL),是因为其被认为是状态无关的。

11、geth客户端使用过吗

(1)Geth是以太坊的客户端。
(2)常用的API:Admin(管理员)、 eth(以太币)、web3、miner(矿工)、net(网络)、personal(个人)、shh、debug(调试)和 txpool(工具)。
(3)geth客户端的帐户存储在keystore目录中。
(4)为了进行交易,必须先解锁该账户 ,可以传入账户地址或账户序号来解锁。

12、熟悉以太坊底层源码
13、什么是重入攻击,如何避免

调用外部合约或将以太币发送到地址的操作要求合约提交外部调用。这些外部调用可以被攻击者劫持,从而迫使合约执行更多的代码(即通过 fallback 回退函数),包括回调原合约本身。所以,合约代码执行过程中将可以“重入”该合约,有点像编程语言里面的间接递归函数调用。
解决方案:
1、(在可能的情况下)将 ether 发送到外部合约时使用内置的 transfer() 函数。transfer() 函数仅发送 2300 Gas 给外部调用,这不足以使目的地址合约调用另一个合约(即重入原合约)。

2、确保所有改变状态变量的逻辑,都发生在以太币被发送出合约(或任何外部调用)之前。最好将对未知地址的外部调用,作为本地函数或代码的最后一个操作。这在以太坊文档中称为检查-效果- 交互(checks-effects-interactions)模式。

3、引入互斥锁。也就是说,添加一个状态变量,在代码执行期间锁定合约,防止重入调用。

14、智能合约安全问题

算术溢出问题,当执行操作需要固定大小的变量来存储超出变量数据类型范围的数 字(或数据)时,会发生数据上溢/下溢 ,使用OppenZepplin.safeMath库解决
重入攻击问题,向以太坊合约账户进行转账,发送Ether的时候,会执行合约账户对 应合约代码的回调函数(fallback)。 在以太坊智能合约中,进行转账操作,一旦向被攻击者劫持的合约地址发起转账操作,迫使执行攻击合约的回调函数,回调函数中包含回调自身代码,将会导致代码执行“重新进入”合约。这种合约漏洞,被称为“重入漏洞”,
第一种技术是(在可能的情况下)将 ether 发送到外部合约时使用内置的 transfer() 函数。transfer() 函数仅发送 2300 Gas 给外部调用,这不足以使目的地址合约调用另一个合约(即重入原合约)。

第二种,是确保所有改变状态变量的逻辑,都发生在以太币被发送出合约(或任何外部调用)之前。在 EtherStore 示例中,EtherStore.sol 的第18和19行应放在第17行之前。最好将对未知地址的外部调用,作为本地函数或代码的最后一个操作。这在以太坊文档中称为检查-效果- 交互(checks-effects-interactions)模式。

第三种是引入互斥锁。也就是说,添加一个状态变量,在代码执行期间锁定合约,防止重入调用。
Ether漏洞
(1)自毁selfdestruct(address)删除所有字节码,并将Ether发送到指定地址
(2)预先发送的Ether:可以提前计算出地址,并且将Ether存入到合约中,避免依赖合约的余额的确切值,用状态变量来记录
可见性漏洞
函数的功能为public 解决:指定合约功能的可见性
随机数误区
Solidity没有rand()功能,暂时没有很好的解决方案
外部合约的引用
外部消息调用时被攻击者利用
解决:1、new创建合约 2、已知外部合约地址。对所有外部地址进行硬编码
短地址攻击
第三方应用程序不验证输入时,交易所不验证ERC20 Token的地址
解决:将所有输入发送到区块链之前进行验证
未检查返回值
call函数调用时,不会发生回滚
解决:使用transfer()功能,transfer会出发回滚
条件竞争/抢先提交
攻击之后设置gasPrice更高的交易使自己的先被验证
解决:1、设置gasPrice的上限,防止超出2、使用commit-reveal方案

15、函数调用方式,view和pure的区别,constant修饰符的含义

view是只读的,能看到某个值,而pure即不可读也不可写,constant修饰符等同于view

16、solidity多继承怎么实现,接口的使用

(1)solidity使用is继承,多继承(一个子类同时集成多个父类),多个父类里有重名的函数和方法时,遵循最远机制。
(2)使用interface关键词修饰。这样的合约不能被编译,但它们可以用作父合约被继承。
无法继承其他合约或接口、 无法定义构造函数、无法定义变量、无法定义结构体、无法定义枚举。

17、函数修饰器

使用关键字modifier定义,使用函数修饰器修饰的代码,会默认追加在函数修饰器 “_” 位置,当修饰器没有执行时,函数会返回对应类型的默认值。有多个函数修饰器时,会按照书写顺序依次执行。

18、https与Http区别

HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
HTTPS和HTTP的区别主要如下
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
  2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
  3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

19、守护进程

守护进程的工作原理
守护进程就是一个在后台运行的一个程序,主要功能就是提供一些系统的服务。
守护进程分为两种类型:独立(Standalone)守护进程和临时(Transient)守护进程,由超级守护进程(super daemon)控制的守护进程。
独立守护进程的工作方式是:当用户或程序提出需求时,独立守护进程会自己为用户或程序提供所需的服务。
临时守护进程的工作方式是:当用户或程序提出需求时会向 xinetd 超级守护进程要求服务,之后,xinetd 再调用相应的临时守护进程,最后再由这个临时守护进程为用户或程序提供所需的服务。

20、TCP和UDP的区别

TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP—用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快

21、其他的公链,比如MOAC ,EOS ,NEO等,他们用的什么共识算法?

MOAC:POW工作量共识机制。优:完全去中心化,节点自由进出。缺:共识达成的周期较长,不适合商业应用。
EOS:DPos股份授权证明机制。优:大幅缩小参与验证和记账节点的数量,可以达到秒级的共识验证。缺:整个共识机制还是依赖于代币,很多商业应用是不需要代币存在的。
NEO:dBFT拜占庭容错算法。优:可以容忍任意类型的错误,记账由多人协同完成,每个区块不会有最终性,无分叉。缺:当1/3或以上记账人停止工作后,系统将无法提供服务。

22、子链、侧链:

侧链:指的是与主链相平行的单独一个区块链,但是它和主链之间可以通过相互了解的协议互联。作为主链的补充,侧链可以提供一些主链不能提供的功能。但是这个互联对共识机制有要求,而且侧链必须有与主链相当的算力才能保证侧链货币的安全性。

子链:指的是在主链的平台来派生出来的具有其他功能的区块链。这些子链不能单独存在,必须通过主链提供的基础设施才能运行,并且免费获得主链的全部用户。

23、单例模式

单例模式:是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例
懒汉:在初始化类的时候,不创建唯一的实例,而是等到真正需要用到的时候才创建。必须加上同步,否则有可能依然创建多个实例。
饿汉:在初始化的时候,就创建了唯一的实例,不管是否需要用到。不需要自己加同步,一定产生唯一的实例。
懒汉模式下,不适合使用太频繁的对象。
而在饿汉模式下,不管是否用到,都会初始化实例。
饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变
详情:https://blog.csdn.net/qq_34207444/article/details/79341334

24、观察者模式,

观察者模式:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时观察一个主题对象。这个主题对象在发生变化时,会通知所有的观察者对象,使它们能够更新自己。
观察者:将自己注册到被观察对象中,被观察对象将观察者存放在一个容器里。
被观察:被观察对象发生了某种变化,从容器中得到所有注册过的观察者,将变化通知观察者。
撤销观察:观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。

25、STO 、ICO、IPO、USDT

IPO(Initial Public Offerings)首次公开募股
ICO(是Initial Coin Offering缩写),首次币发行
STO(Security Token Offer)指的是证券型通证发行,STO就像是ICO与IPO的一种折中,既受到一定程度监管,又可以使证券实通证化,使流通方式更灵活,降低项目方的募资门槛
USDT:中文名称为泰达币,等价于法币的代币,和美元一比一,相当于数字货币的法币。

26、golang高并发实现的基础

协程

27、死锁和死锁解决方案

使用信道是要考虑的一个重要因素是死锁(Deadlock)只读未写与只写未读都会触发死锁,并触发 panic 。
用select方式阻止,在default中放置处理方式。
使用缓冲信道。
简单来讲。把没取走的数据取走,没放入的数据放入, 因为无缓冲信道不能承载数据。

你可能感兴趣的:(区块链常见问题)