搭建BSC Fullnode
要运行BSC全节点,首先需要有服务器,币安官方推荐服务器配置VPS running recent versions of Mac OS X or Linux.IMPORTANT 2T GB of free disk space, solid-state drive(SSD), gp3, 8k IOPS, 250MB/S throughput, read latency <1ms. (if start with snap/fast sync, it will need NVMe SSD)16 cores of CPU and 64 gigabytes of memory (RAM).Suggest m5zn.3xlarge instance type on AWS, c2-standard-16 on Google cloud.A broadband Internet connection with upload/download speeds of 5 megabyte per second我是在aliyun买的VPS,配置是16核64G,系统盘40G,数据盘3000G ESSD...
以Synthetix为例,MEV策略剖析
本文翻译自Robert Miller的Anatomy of an MEV Strategy: Synthetix 几个月前臭名昭著的alpha泄露者KALEB在Flashbots公开的searchers频道发表了下列消息KALBE泄露了关于Synthetix变动的数千万美金的alpha消息。在这个机器人运营商的小房间里分享alpha就像丢给狮子一块红肉一样,在快速看了合约之后可以确认有笔另人晕眩的钱处在危机中。 在接下来的几周,我计划并且尝试去执行策略来捕获KALEB分享的MEV。我会开源我用的代码并一步一步展示整个过程和策略。你将不能运行我的代码去赚钱,但是这篇文章将会教你我是如何设计这个新的搜索者并会包含许多alpha。很自然的,这将会有点技术性,但我会尽量让本文对于非技术读者来说好理解。第一步,识别机会我不是一个Synthetix专家,因此第一步是去学习我将要涉及的操作。具体如下:我找出了相关合约我在Synthetix博客里读了它们的高级别功能并且搜索了相关文档我确保理解了将要实行的治理变动我查找了相关函数总结一下这阶段的工作,Synthetix已经试验了以ETH为抵押去铸...
Bitmap结构在ENSToken里的应用
在ENSToken的合约里看到了Bitmaps的应用,在地址认领空投时用了Merkle树证明来check用户地址和认领数量,进而会对应一个Merkle的index,为了防止重复认领空投,合约里用了OpenZeppelin的Bitmaps库来做位图存储,地址认领成功后,就将对应的index在位图里存true,下次如果再来认领就会判断这个位图,如果为true时就返回错误,以此来防止重复认领空投。BitMaps.BitMap private claimed; /** * @dev Claims airdropped tokens. * @param amount The amount of the claim being made. * @param delegate The address the tokenholder wants to delegate their votes to. * @param merkleProof A merkle proof proving the claim is valid. */ function claimTokens(uint256 amo...
<100 subscribers
搭建BSC Fullnode
要运行BSC全节点,首先需要有服务器,币安官方推荐服务器配置VPS running recent versions of Mac OS X or Linux.IMPORTANT 2T GB of free disk space, solid-state drive(SSD), gp3, 8k IOPS, 250MB/S throughput, read latency <1ms. (if start with snap/fast sync, it will need NVMe SSD)16 cores of CPU and 64 gigabytes of memory (RAM).Suggest m5zn.3xlarge instance type on AWS, c2-standard-16 on Google cloud.A broadband Internet connection with upload/download speeds of 5 megabyte per second我是在aliyun买的VPS,配置是16核64G,系统盘40G,数据盘3000G ESSD...
以Synthetix为例,MEV策略剖析
本文翻译自Robert Miller的Anatomy of an MEV Strategy: Synthetix 几个月前臭名昭著的alpha泄露者KALEB在Flashbots公开的searchers频道发表了下列消息KALBE泄露了关于Synthetix变动的数千万美金的alpha消息。在这个机器人运营商的小房间里分享alpha就像丢给狮子一块红肉一样,在快速看了合约之后可以确认有笔另人晕眩的钱处在危机中。 在接下来的几周,我计划并且尝试去执行策略来捕获KALEB分享的MEV。我会开源我用的代码并一步一步展示整个过程和策略。你将不能运行我的代码去赚钱,但是这篇文章将会教你我是如何设计这个新的搜索者并会包含许多alpha。很自然的,这将会有点技术性,但我会尽量让本文对于非技术读者来说好理解。第一步,识别机会我不是一个Synthetix专家,因此第一步是去学习我将要涉及的操作。具体如下:我找出了相关合约我在Synthetix博客里读了它们的高级别功能并且搜索了相关文档我确保理解了将要实行的治理变动我查找了相关函数总结一下这阶段的工作,Synthetix已经试验了以ETH为抵押去铸...
Bitmap结构在ENSToken里的应用
在ENSToken的合约里看到了Bitmaps的应用,在地址认领空投时用了Merkle树证明来check用户地址和认领数量,进而会对应一个Merkle的index,为了防止重复认领空投,合约里用了OpenZeppelin的Bitmaps库来做位图存储,地址认领成功后,就将对应的index在位图里存true,下次如果再来认领就会判断这个位图,如果为true时就返回错误,以此来防止重复认领空投。BitMaps.BitMap private claimed; /** * @dev Claims airdropped tokens. * @param amount The amount of the claim being made. * @param delegate The address the tokenholder wants to delegate their votes to. * @param merkleProof A merkle proof proving the claim is valid. */ function claimTokens(uint256 amo...
Share Dialog
Share Dialog
先上代码
function randomIndex() internal returns (uint) {
uint totalSize = TOKEN_LIMIT - numTokens;
uint index = uint(keccak256(abi.encodePacked(nonce, msg.sender, block.difficulty, block.timestamp))) % totalSize;
uint value = 0;
if (indices[index] != 0) {
value = indices[index];
} else {
value = index;
}
// Move last value to selected position
if (indices[totalSize - 1] == 0) {
// Array position not initialized, so use position
indices[index] = totalSize - 1;
} else {
// Array position holds a value so use that
indices[index] = indices[totalSize - 1];
}
nonce++;
// Don't allow a zero index, start counting at 1
return value.add(1);
}
在mint时随机指定tokenId,可以实现一定程度的随机分配图片,Meebits只用了一个数组且是O(1)的时间复杂度就实现了随机分配tokenId。
总体思想是,keccak256哈希后对剩余可mint数量totalSize进行取模,得到index值,再到indices里取值。如果indices里的值为0表示这个index没用过,就可以直接用index当做tokenId,然后将最末尾的tokenId(也就是totalSize-1)赋值给indices[index]槽位(如果最末尾的tokenId被分配过,就取indices[totalSize-1]的值赋值给indices[index]槽位),表示如果下次取模后的值又是index,那么就取这时候的最后一个tokenId分配给用户,以此来保证不会重复分配tokenId;如果indices里的值不为0,则说明此index被使用过,那么就要用indices[index]槽位存储的值来做tokenId。
ZombieClub的随机tokenId也应用了此类似的算法,只不过他是在chainLink预言机回调时再去分配tokenId。
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
uint256 tokenId = chainlinkTokenId[requestId];
if (tokenInternalInfo[tokenId].requested && tokenInternalInfo[tokenId].revealId == 0) {
uint256 randomIndex = randomWords[0] % (totalMysteryBoxes - revealedTokens) + revealedTokens;
uint256 revealId = _tokenIdMap(randomIndex);
uint256 currentId = _tokenIdMap(revealedTokens);
tokenIdMap[randomIndex] = currentId;
tokenInternalInfo[tokenId].revealId = uint64(revealId);
revealedTokens ++;
emit RevealReceived(tokenId, revealId);
}
}
先上代码
function randomIndex() internal returns (uint) {
uint totalSize = TOKEN_LIMIT - numTokens;
uint index = uint(keccak256(abi.encodePacked(nonce, msg.sender, block.difficulty, block.timestamp))) % totalSize;
uint value = 0;
if (indices[index] != 0) {
value = indices[index];
} else {
value = index;
}
// Move last value to selected position
if (indices[totalSize - 1] == 0) {
// Array position not initialized, so use position
indices[index] = totalSize - 1;
} else {
// Array position holds a value so use that
indices[index] = indices[totalSize - 1];
}
nonce++;
// Don't allow a zero index, start counting at 1
return value.add(1);
}
在mint时随机指定tokenId,可以实现一定程度的随机分配图片,Meebits只用了一个数组且是O(1)的时间复杂度就实现了随机分配tokenId。
总体思想是,keccak256哈希后对剩余可mint数量totalSize进行取模,得到index值,再到indices里取值。如果indices里的值为0表示这个index没用过,就可以直接用index当做tokenId,然后将最末尾的tokenId(也就是totalSize-1)赋值给indices[index]槽位(如果最末尾的tokenId被分配过,就取indices[totalSize-1]的值赋值给indices[index]槽位),表示如果下次取模后的值又是index,那么就取这时候的最后一个tokenId分配给用户,以此来保证不会重复分配tokenId;如果indices里的值不为0,则说明此index被使用过,那么就要用indices[index]槽位存储的值来做tokenId。
ZombieClub的随机tokenId也应用了此类似的算法,只不过他是在chainLink预言机回调时再去分配tokenId。
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
uint256 tokenId = chainlinkTokenId[requestId];
if (tokenInternalInfo[tokenId].requested && tokenInternalInfo[tokenId].revealId == 0) {
uint256 randomIndex = randomWords[0] % (totalMysteryBoxes - revealedTokens) + revealedTokens;
uint256 revealId = _tokenIdMap(randomIndex);
uint256 currentId = _tokenIdMap(revealedTokens);
tokenIdMap[randomIndex] = currentId;
tokenInternalInfo[tokenId].revealId = uint64(revealId);
revealedTokens ++;
emit RevealReceived(tokenId, revealId);
}
}
No comments yet