重入攻击
- 风险阐述:重入攻击是指在智能合约执行过程中,合约调用外部合约时,外部合约可以再次调用原合约的函数,导致原合约状态被多次错误修改。
- 防范措施:在调用外部合约前改变合约状态,防止重入。例如设置一个标志变量,在合约执行开始时设为
true
,调用外部合约后设为false
,在合约函数入口检查该标志。
- Ruby 代码示例:
class SmartContract
def initialize
@reentrancy_lock = false
end
def transfer(to, amount)
return if @reentrancy_lock
@reentrancy_lock = true
begin
# 执行转账逻辑,例如修改账户余额
self.balance -= amount
to.balance += amount
# 调用外部合约
to.receive(amount)
ensure
@reentrancy_lock = false
end
end
end
整数溢出
- 风险阐述:当对整数进行运算时,结果超出了该整数类型能够表示的范围,就会发生整数溢出。这可能导致意外的结果,如余额变为负数等。
- 防范措施:在进行整数运算前,检查运算结果是否会导致溢出。可以使用 Ruby 的
BigDecimal
库来处理大数运算,避免溢出。
- Ruby 代码示例:
require 'bigdecimal'
class SmartContract
def initialize
@balance = BigDecimal('0')
end
def add_amount(amount)
new_balance = @balance + BigDecimal(amount.to_s)
raise 'Integer overflow' if new_balance < @balance
@balance = new_balance
end
end
未检查的外部调用返回值
- 风险阐述:如果智能合约在调用外部合约后没有检查返回值,外部合约执行失败时,原合约可能继续执行并做出错误的状态修改。
- 防范措施:在调用外部合约后,立即检查返回值是否成功。
- Ruby 代码示例:
class SmartContract
def transfer(to, amount)
success = to.receive(amount)
raise 'Transfer failed' unless success
# 继续处理转账成功后的逻辑,如更新余额
self.balance -= amount
to.balance += amount
end
end
权限控制不当
- 风险阐述:如果智能合约对某些关键操作的权限控制不严,可能导致未经授权的用户执行敏感操作,如修改合约状态、转移资产等。
- 防范措施:明确界定每个函数的调用权限,只有授权用户才能调用。可以通过设置白名单或检查调用者的身份来实现。
- Ruby 代码示例:
class SmartContract
def initialize(admin)
@admin = admin
end
def only_admin
raise 'Unauthorized' unless msg.sender == @admin
end
def update_config(new_config)
only_admin
# 更新配置逻辑
@config = new_config
end
end
时间依赖漏洞
- 风险阐述:智能合约如果依赖系统时间进行某些关键决策,恶意用户可能利用时间差异(如时间戳篡改)来获取不当利益。
- 防范措施:尽量避免依赖系统时间进行关键逻辑判断。如果必须使用,确保时间源的可靠性和不可篡改性,例如使用区块链上的时间戳服务。
- Ruby 代码示例:假设区块链提供一个可靠的时间戳获取方法
blockchain_timestamp
class SmartContract
def unlock_funds(lock_time)
current_time = blockchain_timestamp
raise 'Funds not unlocked yet' if current_time < lock_time
# 执行解锁资金逻辑
end
end