我最近了解到一个涉及合约的黑客行为,你有 10% 的机会铸造稀有的 NFT。
黑客能够看到关于它是稀有还是常规的决定,并在它发生之前取消了铸币厂。这是代码:
uint256 tokenId = totalSupply();
// Getting random number
uint256 rand = getRandom(tokenId);
// Store transaction datas
TransactionData memory transaction = TransactionData(
_minter,
block.timestamp,
_amount
);
transactions.push(transaction);
transactionsForAddress[_minter].push(transaction);
uint256 typeId = getRandomType(rand);
uint256 level = gen1
? typeId == 0 ? _regular : _rare
: 1;
// Store NFT Metadata
nfts.push(NFT(tokenId, typeId, level));
_safeMint(_minter, tokenId);
emit TokenMinted(_minter, tokenId);
}
这怎么可能?是因为铸币厂是在另一个功能决定之后完成的吗?
如果是这样,这是否意味着每个函数都在单独的块中执行?
我目前正在研究一个,不想犯同样的错误
编辑:询问随机功能:
function getRandom(uint256 _seed) internal view returns (uint256) {
return
uint256(
keccak256(
abi.encodePacked(
blockhash(block.number + 4),
tx.origin,
blockhash(block.number + 2),
blockhash(block.number + 3),
blockhash(block.number + 1),
_seed,
block.timestamp
)
)
);
}
function getRandomType(uint256 _seed) internal pure returns (uint256) {
// Generate number between 0 and 9
if (uint256(uint256(keccak256(abi.encode(_seed, 5))) % 10) == 0) {
// 10% luck, 1 = RARE
return 1;
} else {
// 90% luck, 0 = NORMAL
return 0;
}
}
谢谢