前言:
如今各位老铁们对“javascript如何设置居中”大约比较关切,咱们都需要学习一些“javascript如何设置居中”的相关文章。那么小编在网上收集了一些对于“javascript如何设置居中””的相关资讯,希望看官们能喜欢,姐妹们快快来了解一下吧!目录
开始
• 让我们构建一些很酷的东西。• 什么是 DAO?
为 DAO 设置客户端应用程序
• 获取客户端代码 + 获取设置。• 将“连接到钱包”添加到您的 DAO 仪表板。
创建会员 NFT
• 部署你的 NFT 包。• 部署 NFT 元数据。• 让用户铸造你的 NFT。
创建代币+治理
• 部署 ERC-20 合约。• 在 DAO Dashboard 上展示代币持有者。• ⚖️ 建库+治理。• ✅ 让用户对提案进行投票。
收尾工作
• 删除您的管理员权限并处理基本错误。• 完成并庆祝。 创建代币+治理 部署 ERC-20 合约
我们的成员现在有一个 NFT 来证明自己作为我们 DAO 的成员。很好。让我们更进一步。让我们实际创建一个“治理代币”空投给我们的会员。
你可能还记得这里[1]的 ENS DAO 治理代币空投。这是什么意思呢?为什么“治理代币”现在[2]市值近十亿美元?
基本上,治理代币允许用户对提案进行投票。例如,提案可能会说“我希望 Naruto DAO 向0xf79a3bb8d5b93686c4068e2a97eaec5fe4843e7d钱包地址发送 100,000 美元 HOKAGE ,以成为尊贵成员”。然后,成员将对其进行投票。
拥有更多治理令牌的用户更强大。通常,代币会奖励给带来最大价值的社区成员。
例如,对于 ENS 空投,获得最多代币的人是核心开发团队和 Discord 中的活跃用户。但是,根据您持有 ENS 域(例如farza.eth)的时间长短,您也会收到 ENS DAO 令牌。顺便说一句,如果您不知道的话,一个ENS 名称就是一个 NFT。
因此,您拥有此 NFT 的时间越长,您获得的代币就越多。
为什么?因为 ENS 团队希望网络的早期支持者得到奖励。这是他们的公式:
我想说明的是,这是一个自定义的公式!你的DAO也可以有一个自定义的公式。你的DAO也可以有一个自定义的公式。也许你还想根据人们拥有会员资格NFT的时间长短,对你的DAO中的人给予更多奖励。这一切都取决于你。
部署你的代币
让我们创建和部署我们的代币智能合约!前往scripts/5-deploy-token.js并添加:
import { AddressZero } from "@ethersproject/constants";import sdk from "./1-initialize-sdk.js";(async () => { try { // Deploy a standard ERC-20 contract. const tokenAddress = await sdk.deployer.deployToken({ // What's your token's name? Ex. "Ethereum" name: "NarutoDAO Governance Token", // What's your token's symbol? Ex. "ETH" symbol: "HOKAGE", // This will be in case we want to sell our token, // because we don't, we set it to AddressZero again. primary_sale_recipient: AddressZero, }); console.log( "✅ Successfully deployed token contract, address:", tokenAddress, ); } catch (error) { console.error("failed to deploy token contract", error); }})();
我们调用sdk.deployer.deployToken,为你部署一个标准的ERC-20 代[3]币合约,这是以太坊上所有大量代币所采用的标准。你需要给它的只是你的令牌的name和symbol!玩得开心,当然不要模仿我。我希望你正在构建一些你自己认为很酷的东西!
在这里,我给我的令牌符号 HOKAGE。如果你不知道那是什么——看看这个[4],哈哈。TLDR:如果你是hokage,你就是有史以来最好的忍者之一。
顺便说一句——你可以在这里[5]看到 thirdweb 使用的确切合同。
这是我运行它时得到的结果:
buildspace-dao-starter % node scripts/5-deploy-token.js SDK initialized by address: 0xF11D6862e655b5F4e8f62E00471261D2f9c7E380✅ Successfully deployed token contract, address: 0xF93B8AE0a84325D1d7Aa09593DCA3Ad5Fe868eA7
轰!它部署了一个新的代币合约。如果您前往[6]并搜索令牌模块的地址,您将看到刚刚部署的合约。同样,您会看到它从您的钱包中部署,因此您拥有它。
您甚至可以将您的令牌作为自定义令牌添加到 Metamask。
只需单击“导入令牌”:
然后,粘贴您的 ERC-20 合约地址,您将看到 Metamask 神奇地自动抓取您的代币符号:
然后,回到你的钱包,向下滚动,然后可以了!
您正式拥有自己的令牌:)。
创建你的代币供应
目前,可供人们索取的代币为零。我们的 ERC-20 合约并不知道有多少代币可用。我们必须告诉它!
前往6-print-money.js并添加:
import sdk from "./1-initialize-sdk.js";(async () => { try { // This is the address of our ERC-20 contract printed out in the step before. const token = await sdk.getContract("INSERT_TOKEN_ADDRESS", "token"); // What's the max supply you want to set? 1,000,000 is a nice number! const amount = 1_000_000; // Interact with your deployed ERC-20 contract and mint the tokens! await token.mint(amount); const totalSupply = await token.totalSupply(); // Print out how many of our token's are out there now! console.log("✅ There now is", totalSupply.displayValue, "$HOKAGE in circulation"); } catch (error) { console.error("Failed to print money", error); }})();
请记住,此处插入的地址是您的代币合约地址。如果您输入错误的地址,您可能会收到类似这样的错误:“UNPREDICTABLE_GAS_LIMIT”。
同样,如果你丢失了这个地址,你可以参考你很酷的thirdweb仪表板![7]您现在应该看到代币合约已经部署!
因此,这里我们实际上是在铸造代币供应量,并将我们想要铸造的代币amount设置为最大供应量。
这是我运行脚本时得到的结果:
buildspace-dao-starter % node scripts/6-print-money.js Your app address is: 0xa002D595189bF9D50D5897C64b6e07BE5bdEe9b8✅ There now is 1000000.0 $HOKAGE in circulation
现在是史诗般的部分。回到 Etherscan 中的 ERC-20 合约。您现在将看到您拥有自己的令牌跟踪器!
继续并单击跟踪器,您将看到所有供应信息以及以下内容:谁持有您的代币,谁在转移代币,以及转移了多少代币。您还会在这里看到我们有一个“最大总供应量”。
很酷。我们用几行 Javascript 完成了这一切。这很疯狂。如果你想大声笑,你可以在这一点上制作下一个纪念币。
✈️空投它
现在是空投时间。现在你可能是你的 DAO 的唯一成员,没关系!
打开7-airdrop-token.js并添加以下代码:
import sdk from "./1-initialize-sdk.js";(async () => { try { // This is the address to our ERC-1155 membership NFT contract. const editionDrop = await sdk.getContract("INSERT_EDITION_DROP_ADDRESS", "edition-drop"); // This is the address to our ERC-20 token contract. const token = await sdk.getContract("INSERT_TOKEN_ADDRESS", "token"); // Grab all the addresses of people who own our membership NFT, which has // a tokenId of 0. const walletAddresses = await editionDrop.history.getAllClaimerAddresses(0); if (walletAddresses.length === 0) { console.log( "No NFTs have been claimed yet, maybe get some friends to claim your free NFTs!", ); process.exit(0); } // Loop through the array of addresses. const airdropTargets = walletAddresses.map((address) => { // Pick a random # between 1000 and 10000. const randomAmount = Math.floor(Math.random() * (10000 - 1000 + 1) + 1000); console.log("✅ Going to airdrop", randomAmount, "tokens to", address); // Set up the target. const airdropTarget = { toAddress: address, amount: randomAmount, }; return airdropTarget; }); // Call transferBatch on all our airdrop targets. console.log(" Starting airdrop..."); await token.transferBatch(airdropTargets); console.log("✅ Successfully airdropped tokens to all the holders of the NFT!"); } catch (err) { console.error("Failed to airdrop tokens", err); }})();
这是一个很大的问题。但你现在已经是第三网络的专家了,Ezpz。
首先,您会看到我们需要editionDrop和token合同,因为我们将与这两个合同进行交互。
我们需要首先从 editionDrop 中获取NFT 持有者,然后使用token上的函数将他们的代币铸造出来。
我们getAllClaimerAddresses用来获取所有拥有我们 NFT w/tokenId "0" 会员资格的人的walletAddresses。
从那里,我们遍历所有walletAddresses并选择一个randomAmount令牌空投给每个用户,并将这些数据存储在airdropTarget字典中。
最后,我们在我所有的airdropTargets上运行transferBatch。就是这样!transferBatch将自动循环遍历所有目标,并发送令牌!
当我运行脚本时,这是我得到的:
buildspace-dao-starter % node scripts/7-airdrop-token.js SDK initialized by address: 0xF11D6862e655b5F4e8f62E00471261D2f9c7E380✅ Going to airdrop 8761 tokens to 0xF11D6862e655b5F4e8f62E00471261D2f9c7E380✅ Going to airdrop 9606 tokens to 0x14fb3a9B317612ddc6d6Cc3c907CD9F2Aa091eE7✅ Going to airdrop 7376 tokens to 0xF79A3bb8d5b93686c4068E2A97eAeC5fE4843E7D✅ Going to airdrop 9418 tokens to 0xc33817A8e3DD0687FB830666c2658eBBf4696245✅ Going to airdrop 8311 tokens to 0xe50b229DC4D053b95fA586EBd1874423D9Be5145✅ Going to airdrop 9603 tokens to 0x7FA42Aa5BF1CA8084f51F3Bab884c3aCB5180C86 Starting airdrop...✅ Successfully airdropped tokens to all the holders of the NFT!
yooo。你刚刚做了一个空投,太棒了!在我的例子中,你可以看到我的 DAO 中有 6 个独特的成员,他们都收到了空投。就您而言,现在可能只有您一个人!随着更多成员的加入,请随时再次运行此脚本。
在现实世界中,空投通常只发生一次。但是,我们现在只是在闲逛,所以没关系。另外,这个世界没有真正的规则,哈哈。如果您想每天进行 4 次空投,那就去吧!
您可以像 ENS 一样创建自己的小空投公式,例如:
你会想——“收到代币的人将对 DAO 拥有更多的权力。这个好吗?最大的代币持有者会为 DAO 做正确的事吗?”。这涉及到非常广泛的代币经济学主题,您可以在此处[8]阅读。
好的,现在如果我回到我在 Etherscan 上的 ERC-20 合约,我可以看到我所有的新代币持有者以及他们拥有多少$HOKAGE。
让我们开始吧。
在 DAO Dashboard 上展示代币持有者 在网络应用程序上检索代币持有者
如果我们的 DAO 的所有成员能够轻松地看到 DAO 中持有代币的所有人以及他们持有的代币数量,那就太好了。为此,我们需要从客户端实际调用我们的智能合约并检索该数据。
前往App.jsx,然后在editionDrop下方,添加您的token.
// Initialize our token contractconst { contract: token } = useContract('INSERT_TOKEN_ADDRESS', 'token');
我们需要这个,以便我们可以与 ERC-1155 合约和 ERC-20 合约进行交互。从 ERC-1155,我们将获得所有成员的地址。从 ERC-20 中,我们将检索每个成员拥有的代币数。
接下来,在const hasClaimedNFT...下面添加以下代码:
// Holds the amount of token each member has in state.const [memberTokenAmounts, setMemberTokenAmounts] = useState([]);// The array holding all of our members addresses.const [memberAddresses, setMemberAddresses] = useState([]);// A fancy function to shorten someones wallet address, no need to show the whole thing.const shortenAddress = (str) => { return str.substring(0, 6) + '...' + str.substring(str.length - 4);};// This useEffect grabs all the addresses of our members holding our NFT.useEffect(() => { if (!hasClaimedNFT) { return; } // Just like we did in the 7-airdrop-token.js file! Grab the users who hold our NFT // with tokenId 0. const getAllAddresses = async () => { try { const memberAddresses = await editionDrop?.history.getAllClaimerAddresses( 0, ); setMemberAddresses(memberAddresses); console.log(' Members addresses', memberAddresses); } catch (error) { console.error('failed to get member list', error); } }; getAllAddresses();}, [hasClaimedNFT, editionDrop?.history]);// This useEffect grabs the # of token each member holds.useEffect(() => { if (!hasClaimedNFT) { return; } const getAllBalances = async () => { try { const amounts = await token?.history.getAllHolderBalances(); setMemberTokenAmounts(amounts); console.log(' Amounts', amounts); } catch (error) { console.error('failed to get member balances', error); } }; getAllBalances();}, [hasClaimedNFT, token?.history]);// Now, we combine the memberAddresses and memberTokenAmounts into a single arrayconst memberList = useMemo(() => { return memberAddresses.map((address) => { // We're checking if we are finding the address in the memberTokenAmounts array. // If we are, we'll return the amount of token the user has. // Otherwise, return 0. const member = memberTokenAmounts?.find(({ holder }) => holder === address); return { address, tokenAmount: member?.balance.displayValue || '0', }; });}, [memberAddresses, memberTokenAmounts]);
乍一看好像很多!但只要知道我们正在做三件事:
1. 我们调用getAllClaimerAddresses从我们的 ERC-1155 合约中获取持有 NFT 的所有成员的地址。2. 我们调用getAllHolderBalances获取在 ERC-20 合约中持有我们代币的每个人的代币余额。3. 我们将数据组合成memberList数组,该数组结合了成员的地址和他们的代币余额。随便看看这里[9]useMemo有什么。这是 React 中存储计算变量的一种奇特方式。
现在,您可能会问自己,“我们不能直接使用`getAllHolderBalances获取所有持有我们代币的人吗?”。好吧,基本上,有人可以在我们的 DAO 中并持有零代币!而且,这也没关系。所以仍然希望他们出现在名单上。
在我的控制台中,我得到了类似这样的信息,我现在成功地从我的两个合约——ERC-20 和我的 ERC-1155 中检索数据。是的!!随意在这里改动并检查所有数据。
在 DAO Dashboard 上呈现成员数据
现在我们已经在 React 应用程序的状态中很好地保存了所有数据,让我们渲染它。
替换 if (hasClaimedNFT) { }为以下内容:
// If the user has already claimed their NFT we want to display the internal DAO page to them// only DAO members will see this. Render all the members + token amounts.if (hasClaimedNFT) { return ( <div className="member-page"> <h1>DAO Member Page</h1> <p>Congratulations on being a member</p> <div> <div> <h2>Member List</h2> <table className="card"> <thead> <tr> <th>Address</th> <th>Token Amount</th> </tr> </thead> <tbody> {memberList.map((member) => { return ( <tr key={member.address}> <td>{shortenAddress(member.address)}</td> <td>{member.tokenAmount}</td> </tr> ); })} </tbody> </table> </div> </div> </div> );}
很简单!我们只是在渲染一个漂亮的小表格,它将展示我们的memberList. 一旦你检查了你的页面,你会看到类似下面的截图!注意:没有居中,这是故意的。稍后我们将添加其他内容!
现在,我们有一个地方可以让我们的所有成员在一个内部的、由令牌控制的DAO仪表板上看到其他成员。真棒 :)。
Github源码:
原文链接:
引用链接
[1] 你可能还记得这里:
[2] 为什么“治理代币”现在:
[3] ERC-20 代:
[4] 这个:
[5] 顺便说一句——你可以在这里:
[6] :
[7] thirdweb仪表板!:
[8] 此处:
[9] 这里:
标签: #javascript如何设置居中