搭建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
最近比较关注NFT市场,发现有一个项目3Larders在随机开图上做得比较好,采用chainlink随机数当种子,再对tokenId与元数据的映射进行洗牌,确保图片的随机分配,在此点赞!因为查看了很多NFT项目,在随机开图方面都没有做到公开透明,3Landers很是难得。我特别花了些时间对它的合约、mint与开图进行了分析。
合约地址是0xb4d06d46A8285F4EC79Fd294F78a881799d8cEd9,项目方用0x8cBc5c6f260bEf0f9edB71219A61A1c52062A586这个地址来创建合约

setAirdropRole 设置自己的地址为可以发放空投的地址。项目方保留了200个在金库里做为后续活动使用,他在这里采用airdrop的方式mint到指定的地址,后面会提到
setTransactionLimit 设置单笔交易白单可mint数量,单笔交易公售可mint数量,一个白单可mint数量
setWhitelistSigningAddress 设置验证白单签名的地址
setPrivateSaleCap 设置白单mint总量
setDefaultURI 设置默认元数据URI,这个相当于盲盒的元数据,设置的是一个http地址
https://ipfs.io/ipfs/QmNWziXfkdZRTY6ZQHkHGUe8smUCNGPT4umrpQ8KVjqNDB但实际是存在IPFS上的
setDiscountBlockSize 设置公售荷兰拍多少个区块进行价格递减,这里设置的是90个块
setPriceDecayParams 设置荷拍的最低价和递减金额,这里设置的是递减0.1 eth,最低到0.15 eth
enablePrivateSale 设置状态为白单mint状态
0x92fb4967 setPrivateSaleConfig 设置白单mint的开始和结束区块
推荐一个工具https://github.com/cleanunicorn/abi2signature,可以方便的根据abi计算出函数signature,对于解读tx有帮助

airdrop 空投前面200个NFT给金库地址
setReserve 设置金库保留的数量为200
中间有三笔airdrop是失败的,因为合约部署时默认金库保留数量是169,因此那三笔airdrop超过了169,所以失败了,他在重新setReserve改为200后,又再次airdrop成功
0x92fb4967 setPrivateSaleConfig 又再次设置白单mint的开始和结束区块,这笔应该是误操作,重复设置了
updateRoyaltyInfoForCollectionIfOwner 设置LooksRare交易的项目方版权费抽成比例和收款地址,这里设置了6.5%
transferOwnership 转移合约owner给另一个地址0xBDD7EFd925980cD07A6654227647cE244ACA8021
接着看0xBDD7EFd925980cD07A6654227647cE244ACA8021地址的操作

0xb87ced4e setPublicSaleConfig 设置公售的开始和结束区块
enablePublicSale 设置状态为公售状态
公售5分24秒就抢完了剩下的3337个,其中337个是白单mint剩余的,gas拉到了1750gwei,还是比较火爆的
release 分配收到的eth给5个地址,这里用了OpenZeppelin的PaymentSplitter做份额记录和分配
0xacf14efb 设置Rarible的版权费
requestChainlinkVRF 请求chainlink随机数种子
随后chainlink回调交易0xb5151c81935994690872bd1266205f8bfcdc217dca92706293b41f6fd19d1d71,对seed进行了设置
setBaseURI 设置开盒后的元数据URI为
https://0xstudio.mypinata.cloud/ipfs/QmRSK4yjjYXFWKtwZ6W4y3zXPPbQhvE3nAgG87aSjjTP1f/,实际是一个ipfs的目录
setRevealBlock 设置开盒区块
到这里NFT就开盒结束了。NFT的元数据是通过tokenURI进行获取的,现在来看下随机开盒如何实现
function tokenURI(uint256 tokenId)
public
view
override(ERC721)
returns (string memory)
{
require(tokenId < totalSupply()+1, "Token not exist.");
return
isRevealed()
? string(
abi.encodePacked(
_tokenBaseURI,
getMetadata(tokenId),
".json"
)
)
: _defaultURI;
}
function getMetadata(uint256 tokenId) public view returns (string memory) {
if (_msgSender() != owner()) {
require(tokenId < totalSupply(), "Token not exists.");
}
if (!isRevealed()) return "default";
uint256[] memory metadata = new uint256Unsupported embed;
for (uint256 i = 1; i <= maxSupply; i += 1) {
metadata[i] = i;
}
for (uint256 i = 2; i <= maxSupply; i += 1) {
uint256 j = (uint256(keccak256(abi.encode(seed, i))) % (maxSupply)) + 1;
if(j>=2 && j<= maxSupply) {
(metadata[i], metadata[j]) = (metadata[j], metadata[i]);
}
}
return Strings.toString(metadata[tokenId]);
}
从tokenURI函数可以看到,未开盒时用_defaultURI显示元数据,开盒后用_tokenBaseURI加用getMetadata的结果显示元数据,以此来实现盲盒与开盒。getMetadata用seed随机数进行顺序清洗,对参数进行了keccak256哈希再用总数来取模,然后顺序对调,进行洗牌,保证了每次getMetadata的洗牌后顺序都一样。这套算法基于变量seed,而变量seed又基于chainlink,因此规避了开盒的人为操纵,增加了项目的透明度和公平性,值得学习。
最近比较关注NFT市场,发现有一个项目3Larders在随机开图上做得比较好,采用chainlink随机数当种子,再对tokenId与元数据的映射进行洗牌,确保图片的随机分配,在此点赞!因为查看了很多NFT项目,在随机开图方面都没有做到公开透明,3Landers很是难得。我特别花了些时间对它的合约、mint与开图进行了分析。
合约地址是0xb4d06d46A8285F4EC79Fd294F78a881799d8cEd9,项目方用0x8cBc5c6f260bEf0f9edB71219A61A1c52062A586这个地址来创建合约

setAirdropRole 设置自己的地址为可以发放空投的地址。项目方保留了200个在金库里做为后续活动使用,他在这里采用airdrop的方式mint到指定的地址,后面会提到
setTransactionLimit 设置单笔交易白单可mint数量,单笔交易公售可mint数量,一个白单可mint数量
setWhitelistSigningAddress 设置验证白单签名的地址
setPrivateSaleCap 设置白单mint总量
setDefaultURI 设置默认元数据URI,这个相当于盲盒的元数据,设置的是一个http地址
https://ipfs.io/ipfs/QmNWziXfkdZRTY6ZQHkHGUe8smUCNGPT4umrpQ8KVjqNDB但实际是存在IPFS上的
setDiscountBlockSize 设置公售荷兰拍多少个区块进行价格递减,这里设置的是90个块
setPriceDecayParams 设置荷拍的最低价和递减金额,这里设置的是递减0.1 eth,最低到0.15 eth
enablePrivateSale 设置状态为白单mint状态
0x92fb4967 setPrivateSaleConfig 设置白单mint的开始和结束区块
推荐一个工具https://github.com/cleanunicorn/abi2signature,可以方便的根据abi计算出函数signature,对于解读tx有帮助

airdrop 空投前面200个NFT给金库地址
setReserve 设置金库保留的数量为200
中间有三笔airdrop是失败的,因为合约部署时默认金库保留数量是169,因此那三笔airdrop超过了169,所以失败了,他在重新setReserve改为200后,又再次airdrop成功
0x92fb4967 setPrivateSaleConfig 又再次设置白单mint的开始和结束区块,这笔应该是误操作,重复设置了
updateRoyaltyInfoForCollectionIfOwner 设置LooksRare交易的项目方版权费抽成比例和收款地址,这里设置了6.5%
transferOwnership 转移合约owner给另一个地址0xBDD7EFd925980cD07A6654227647cE244ACA8021
接着看0xBDD7EFd925980cD07A6654227647cE244ACA8021地址的操作

0xb87ced4e setPublicSaleConfig 设置公售的开始和结束区块
enablePublicSale 设置状态为公售状态
公售5分24秒就抢完了剩下的3337个,其中337个是白单mint剩余的,gas拉到了1750gwei,还是比较火爆的
release 分配收到的eth给5个地址,这里用了OpenZeppelin的PaymentSplitter做份额记录和分配
0xacf14efb 设置Rarible的版权费
requestChainlinkVRF 请求chainlink随机数种子
随后chainlink回调交易0xb5151c81935994690872bd1266205f8bfcdc217dca92706293b41f6fd19d1d71,对seed进行了设置
setBaseURI 设置开盒后的元数据URI为
https://0xstudio.mypinata.cloud/ipfs/QmRSK4yjjYXFWKtwZ6W4y3zXPPbQhvE3nAgG87aSjjTP1f/,实际是一个ipfs的目录
setRevealBlock 设置开盒区块
到这里NFT就开盒结束了。NFT的元数据是通过tokenURI进行获取的,现在来看下随机开盒如何实现
function tokenURI(uint256 tokenId)
public
view
override(ERC721)
returns (string memory)
{
require(tokenId < totalSupply()+1, "Token not exist.");
return
isRevealed()
? string(
abi.encodePacked(
_tokenBaseURI,
getMetadata(tokenId),
".json"
)
)
: _defaultURI;
}
function getMetadata(uint256 tokenId) public view returns (string memory) {
if (_msgSender() != owner()) {
require(tokenId < totalSupply(), "Token not exists.");
}
if (!isRevealed()) return "default";
uint256[] memory metadata = new uint256Unsupported embed;
for (uint256 i = 1; i <= maxSupply; i += 1) {
metadata[i] = i;
}
for (uint256 i = 2; i <= maxSupply; i += 1) {
uint256 j = (uint256(keccak256(abi.encode(seed, i))) % (maxSupply)) + 1;
if(j>=2 && j<= maxSupply) {
(metadata[i], metadata[j]) = (metadata[j], metadata[i]);
}
}
return Strings.toString(metadata[tokenId]);
}
从tokenURI函数可以看到,未开盒时用_defaultURI显示元数据,开盒后用_tokenBaseURI加用getMetadata的结果显示元数据,以此来实现盲盒与开盒。getMetadata用seed随机数进行顺序清洗,对参数进行了keccak256哈希再用总数来取模,然后顺序对调,进行洗牌,保证了每次getMetadata的洗牌后顺序都一样。这套算法基于变量seed,而变量seed又基于chainlink,因此规避了开盒的人为操纵,增加了项目的透明度和公平性,值得学习。
No comments yet