未知数据源 2024年10月02日
Build NFT metadata access control with Ethereum signatures and AWS Lambda authorizers
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

NFT 已经成为全球关注的焦点,它是一种创建独一无二的数字资产的机制,可以立即验证其真实性,在用户之间轻松交换,并且可以无限编程,因此 NFT 可以用于各种用例和行业。本文介绍了一种使用 AWS Lambda 授权器和以太坊签名来授权访问存储在 Amazon S3 中的 NFT 元数据的解决方案,从而仅允许以太坊区块链上该 NFT 的所有者查看存储在 Amazon S3 中的内容。

🚀 NFT 由三个主要部分组成: - 在区块链上由智能合约根据既定标准(例如 ERC721 或 ERC1155)编排的链上数据。 - 用于特定 NFT 的令牌 URI 可检索的 JSON 元数据文件,该文件定义了 NFT 代表的属性和内容(例如游戏内角色的统计数据)。 - 可选的包含附加内容的媒体文件,该文件在 JSON 元数据文件中引用。

💡 为了控制对 NFT 元数据的访问,可以使用 Amazon S3 来存储 NFT 元数据,并通过 Amazon API Gateway 公开一个 URI 来访问该内容,该网关由 Lambda 授权器支持。该授权器可以验证和授权检索元数据文件的请求,方法是验证来自与以太坊兼容的区块链钱包的签名,以确保只有所有者(或其他授权方)能够访问元数据文件。

🔑 以太坊兼容的区块链钱包封装了此公钥/私钥对,并使用椭圆曲线数字签名算法 (ECDSA) `secp256k1` 来生成用于协议的数字签名,这与比特币中使用的相同加密实现。区块链钱包包含用户的私钥和从公钥派生的地址,并允许用户签署交易并查看其地址拥有的加密货币或其他数字资产的所有权。

🛡️ 为了验证此消息,签名字段和原始消息(构成哈希)作为输入提供给以太坊签名验证函数,例如 Ethers.js utils.recoverAddress,以验证消息实际上是否由地址所有者签名。如果验证函数返回原始消息中提供的地址,则它可以被认为是有效的签名,以验证给定地址的所有权,进而验证给定 NFT 的所有权。

🚀 本解决方案使用 Amazon S3 存储 NFT 元数据,并使用 Amazon API Gateway 和 Lambda 授权器来限制对该内容的访问,以便只有 NFT 的所有者才能查看存储在 Amazon S3 中的内容。该解决方案利用了以太坊签名来验证请求,以确保只有 NFT 的所有者能够访问元数据。

☁️ 存储 NFT 元数据的其他去中心化替代方案(如 IPFS)通常需要所有者维护自己的 IPFS 节点或承担为保证文件在 IPFS 上可用而支付固定服务的负担。在 IPFS 中,不经常检索的文件可能会从 IPFS 节点的存储中删除,这需要额外的努力才能将这些文件固定在 IPFS 节点上以确保该内容的可用性。

💰 与流行的 IPFS 固定服务相比,该服务每 GB 费用为 0.15 美元,Amazon S3 在 `us-east-1` 区域存储相同类型的内容只需每 GB 0.02 美元,节省了近 85%。当然,成本并非唯一因素 - NFT 社区的基石是去中心化,在某些情况下,去中心化选项(如 IPFS)或中心化选项(如 Amazon S3)都是理想的选择。

🌐 使用 Amazon S3 存储 NFT 元数据可以为 NFT 创建者提供一种经济高效且可扩展的方式来存储和管理其 NFT。Amazon S3 还提供高可用性和安全性,确保 NFT 元数据始终可用且安全。

🔐 使用 Lambda 授权器可以确保只有 NFT 的所有者才能访问存储在 Amazon S3 中的元数据。这通过使用以太坊签名来验证请求来实现。通过使用 Lambda 授权器,NFT 创建者可以放心地将他们的 NFT 元数据存储在 Amazon S3 中,而无需担心未经授权的访问。

🚀 该解决方案可以帮助 NFT 创建者和开发人员构建更安全、更可靠的 NFT 应用程序。通过使用 Amazon S3 和 Lambda 授权器,他们可以控制对 NFT 元数据的访问,并确保他们的 NFT 始终可用且安全。

<p>Non-fungible tokens (NFTs) have captured global attention as a mechanism for creating one-of-a-kind digital assets that can be instantly verified as authentic, easily exchanged between users, and made infinitely programmable such that NFTs can be used for a variety of use cases and industries.</p><p>At its core, NFTs are a form of digital asset or token accounted for on a blockchain network via a smart contract. This smart contract is comprised of code that allows users to mint (create), burn (delete), and exchange NFTs on public blockchains like Ethereum, where an NFT is in many cases as simple as a key-value pair stored on that blockchain. This key-value pair is often a unique identifier (the token) mapped to an owner’s blockchain wallet address.</p><p>Naturally, popular implementations of NFTs such as digital art or video game items require other metadata and content to function properly, which is stored on an off-chain data store varying from centralized options like <a href="http://aws.amazon.com/s3&quot; target="_blank" rel="noopener noreferrer">Amazon Simple Storage Service</a> (Amazon S3) to decentralized file storage systems like <a href="https://docs.ipfs.io/concepts/what-is-ipfs/&quot; target="_blank" rel="noopener noreferrer">Interplanetary File System (IPFS)</a>. In addition to the key-value pair for token identifier and owner address, NFT smart contracts often store a URI that points to that particular token’s metadata or content. As a result, this public URI can be used by virtually anyone to access the content associated with an NFT, which is perfectly reasonable for some use cases but unviable for others, such as where an NFT entitles its owner to an exclusive piece of content that they don’t wish to share with the public (such as a movie, song, or piece of art).</p><p>In this post, we outline a solution to this challenge, using <a href="http://aws.amazon.com/lambda&quot; target="_blank" rel="noopener noreferrer">AWS Lambda</a> authorizers and Ethereum signatures to authorize access to NFT metadata stored in Amazon S3, allowing only the owner of that NFT on the Ethereum blockchain to see the content stored in Amazon S3.</p><h2>How to control access to NFT metadata with AWS services</h2><p>NFTs are comprised of three major components:</p><ul><li>On-chain data marshaled by smart contracts according to established standards (for example, ERC721 or ERC1155)</li><li>A JSON metadata file retrievable by the token URI for a given NFT that defines the attributes and content the NFT represents (such as the stats for an in-game character)</li><li>Optionally, a media file with additional content referenced in the JSON metadata file</li></ul><p>As described earlier, an NFT is minted on a public blockchain, and anyone can publicly visit the stored NFT metadata URI regardless of the content within. Today, most NFTs point to public URIs where the metadata and content is publicly accessible. For many use cases, content must be accessible to the owner of the NFT at any given time, but be restricted to the general public if required by the owner.</p><p>In this solution, you can store the NFT metadata on Amazon S3 and expose a URI to access that content via <a href="https://aws.amazon.com/api-gateway&quot; target="_blank" rel="noopener noreferrer">Amazon API Gateway</a> backed by a Lambda authorizer that determines who can access that content. With this authorizer, we can verify and authorize requests to retrieve the metadata file by verifying a signature from an Ethereum-compatible blockchain wallet to ensure only the owner (or other authorized party) is able to access the metadata file.</p><h2>Why use Amazon S3 to store NFT metadata?</h2><p>Amazon S3 is an object storage service offering industry-leading scalability, data availability, security, and performance. Amazon S3 and its configurable storage tiering is an economical choice for storing data at high scale and for a long period of time.</p><p>For storing NFT metadata, Amazon S3 enables an NFT creator to store both metadata JSON files as well as supporting content in an easily retrievable way, either directly from Amazon S3 from the web, or integrating a global content delivery network such as <a href="https://aws.amazon.com/cloudfront/&quot; target="_blank" rel="noopener noreferrer">Amazon CloudFront</a>.</p><p>Other decentralized alternatives for storing NFT metadata and content like IPFS usually require the owner to maintain their own IPFS node or shoulder the burden of paying for a pinning service that will ensure files remain available on IPFS. In IPFS, files that aren’t retrieved often can be dropped out of IPFS node’s storage, which requires additional effort to pin those files on IPFS nodes to ensure availability of that content.</p><p>This added complexity and cost can make it difficult for someone new to decentralized storage options to get started. For example, compared to a popular IPFS pinning service that costs $0.15 per GB, Amazon S3 costs merely $0.02 per GB to store the same types of content in the <code>us-east-1</code> Region, representing almost 85% savings. Naturally, cost is not the only factor—a cornerstone of the NFT community is decentralization, and there are instances where either decentralized options like IPFS or centralized options like Amazon S3 are ideal choices.</p><h2>What constitutes an Ethereum-compatible blockchain wallet?</h2><p>The Ethereum blockchain is an account-based blockchain, meaning the underlying ledger stores states related to user balances and application data mapped by an address that uniquely identifies each user. That address is derived from a public key in a public/private key pair. Following the principles of public key cryptography, the public key can be used to verify that a given transaction or message has been signed by its corresponding private key—this process is the crux of signature verification methods outlined in this post. Specifically, a user can prove the ownership of an address (derived from their public key) simply by signing a message with their private key.</p><p>An Ethereum-compatible blockchain wallet encapsulates this public/private key pair and uses the Elliptic Curve Digital Signature Algorithm (ECDSA) <code>secp256k1</code> to produce digital signatures for use in the protocol, which is the same cryptography implementation used in Bitcoin. A blockchain <em>wallet</em> contains a user’s private key and public key derived addresses, and allows a user to sign transactions and view ownership of cryptocurrency or other digital assets owned by their addresses.</p><p>In this post, our wallet’s private key is what we use to prove ownership of a given address, which in turn proves ownership of a given NFT. We achieve this by producing a signed message using the Ethereum-compatible blockchain wallet private key.</p><h3>Using Ethereum-compatible blockchain wallets to sign and verify messages</h3><p>With an Ethereum-compatible blockchain wallet and its corresponding private key, you can produce a signed message to prove ownership of a given address, which in turn can be used to verify your ownership in a given digital asset on the blockchain. Again, recall that a user’s address is derived from the public key in the wallet’s public/private key pair, and that address is used to record ownership of digital assets on the blockchain ledger.</p><p>Signed messages conform to a general standard format comprised of the <code>message</code> itself, the <code>signature</code>, and the <code>address</code> of the signer. The following code is an example of a message signed using an Ethereum-compatible blockchain wallet:</p><p>To verify this message, the signature field and the original message, constituted as hashes, are provided as inputs to an Ethereum signature verification function <a href="https://docs.ethers.io/v4/api-utils.html#cryptographic-functions&quot; target="_blank" rel="noopener noreferrer">such as Ethers.js utils.recoverAddress</a> to validate that the message was in fact signed by the owner of the address in question. If the verification function returns the address provided in the original message, it can be considered a valid signature to verify the ownership of a given address, and in turn, a given NFT. Remember, signed messages in Ethereum are primarily used to unequivocally prove ownership of a given address by proving who owns the private key used to derive it. Nevertheless, the recipient might still be at risk of a <a href="https://en.wikipedia.org/wiki/Replay_attack&quot; target="_blank" rel="noopener noreferrer">replay attack</a> if it’s the only method used to verify the sender’s identity (see security considerations).</p><h2>Solution overview</h2><p>For your reference, the full source code for this sample solution can be found in the <a href="https://github.com/aws-samples/nft-access-control-lambda-authorizer&quot; target="_blank" rel="noopener noreferrer">GitHub repo</a>.</p><p>The following diagram illustrates our solution architecture.</p><p><img class="alignnone wp-image-24839 size-full" src="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2022/09/22/DBBLOG-2232-image001-v2.png&quot; alt="" width="977" height="502" /></p><h2>Prerequisites</h2><p>If you haven’t yet installed Node.js or NPM, do so before attempting to run the React app. You can install Node.js or NPM using <a href="https://github.com/nvm-sh/nvm&quot; target="_blank" rel="noopener noreferrer">Node Version Manager</a>.</p><p>To deploy the core components of the NFT access control architecture, you use the <a href="https://aws.amazon.com/serverless/sam/&quot; target="_blank" rel="noopener noreferrer">AWS Serverless Application Model</a> (AWS SAM) command line interface tools. To install the AWS SAM CLI, refer to <a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html&quot; target="_blank" rel="noopener noreferrer">Installing the AWS SAM CLI</a>. From the <code>serverless/</code> directory of the repository, run the following AWS SAM CLI command to deploy the infrastructure:</p><p>To produce Ethereum signatures, we use a front-end application. Deploy and start front end app by running following command from <code>client/</code> directory</p><p>Access the front-end app by navigating to localhost:3000 from a modern web browser (such as Google Chrome) with <a href="https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn&quot; target="_blank" rel="noopener noreferrer">MetaMask browser extension</a>. You will be prompted to sign a message with your Ethereum-compatible blockchain wallet via MetaMask.</p><h2>Create an Ethereum-compatible blockchain wallet for deploying your NFT smart contract</h2><p>To sign and pay for a transaction on the Ethereum Rinkeby network, you need an Ethereum wallet. An Ethereum-compatible blockchain wallet is comprised of a private/public key pair. You can create your own Ethereum-compatible blockchain wallet programmatically using popular Ethereum libraries <a href="https://web3js.readthedocs.io/en/v1.5.2/web3-eth-accounts.html&quot; target="_blank" rel="noopener noreferrer">Web3</a> and <a href="https://docs.ethers.io/v5/api/signer/#Wallet&quot; target="_blank" rel="noopener noreferrer">Ethers</a>.</p><p>Note that this method for creating and managing an Ethereum-compatible blockchain wallet private key is not suitable for production spending keys. Do not use this wallet for mainnet Ether!</p><p>Generate the private key using one of the aforementioned libraries and upload to <a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html&quot; target="_blank" rel="noopener noreferrer">AWS Systems Manager Parameter Store</a> as an encrypted string under the name <code>ethSystemKey</code>. Make sure the secure string value excludes the first two characters, <code>0x</code>, of the private key. In this case, we use the wallet created here as a backend signer to deploy smart contracts and mint NFTs on behalf of users.</p><p><a href="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2022/09/20/DBBLOG-2232-image003.jpg&quot;&gt;&lt;img class="alignnone size-full wp-image-24643" src="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2022/09/20/DBBLOG-2232-image003.jpg&quot; alt="" width="1378" height="388" /></a></p><p>Add some test network Ether for the Ethereum Rinkeby test network using the Rinkeby faucet <code>https://faucet.rinkeby.io/&lt;/code&gt; by entering the Ethereum address generated during wallet creation and requesting test tokens. Special care must be taken with spending keys (private keys), and <a href="https://aws.amazon.com/systems-manager/&quot; target="_blank" rel="noopener noreferrer">AWS Systems Manager</a> might not be adequate for wallets that can be used to spend funds on mainnet.</p><p>If you’re having trouble requesting testnet Ether from the Rinkeby faucet, you may use the <a href="https://faucets.chain.link/rinkeby&quot; target="_blank" rel="noopener noreferrer">Chainlink Faucet</a> to get small amounts of testnet Ether.</p><h2>Deploy the NFT smart contract (ERC721)</h2><p>After an Ethereum-compatible blockchain wallet has been created for the backend NFT minting service and funded with testnet Ether, we can deploy the ERC721 token standard smart contract that we use to mint and manage NFTs to the Ethereum testnet. The ERC721 smart contract standard defines methods and functionalities to create and manage NFTs on the blockchain. To deploy the smart contract, first modify the JSON event <code>deploy.json</code> to define the NFT contract details such as the name, ticker symbol, and base URI for the underlying NFT content. The base URI refers to the endpoint where the metadata files reside for each NFT minted via this smart contract. See the following code:</p><p>After the smart contract is deployed, you receive a response containing the transaction hash (ID) and contract address that you use in the next step to mint an NFT using that smart contract.</p><h2>Mint an NFT</h2><p>With the ERC721 smart contract deployed, we can invoke the <code>_safeMint</code> function on the smart contract to mint a new NFT with an incremented unsigned integer token ID. The first NFT created in this smart contract has a token ID of 0, the second has a token ID of 1, and so on.</p><p>To mint, modify the <code>mintAddress</code> variable in the <code>mint.json</code> event file. The <code>mintAddress</code> is the Ethereum address (not necessarily the same address as the one that deployed the contract) that the token ownership is transferred to upon the creation of the NFT. In this case, copy the address from your MetaMask wallet and enter it as the address to mint to. See the following code:</p><p><a href="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2022/09/20/DBBLOG-2232-image005.jpg&quot;&gt;&lt;img class="size-full wp-image-24644 aligncenter" src="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2022/09/20/DBBLOG-2232-image005.jpg&quot; alt="" width="360" height="509" /></a></p><p>This minting function mints a new NFT and assigns its owner to the Ethereum address copied from your MetaMask wallet, and stores the metadata attributes defined in <code>mint.json</code> within an S3 bucket for retrieval later. With the Lambda authorizer deployed earlier, this metadata is only accessible by the owner of the NFT. Any requests to retrieve this metadata are authenticated by verifying an Ethereum signature from your Ethereum-compatible blockchain wallet in MetaMask. The private key signature produced by your wallet proves your ownership of the address that owns the NFT corresponding to the requested metadata.</p><h2>Get the metadata URI</h2><p>To retrieve the metadata for your new NFT, you must first retrieve the metadata URI that was set in earlier steps. This metadata URI points to an API endpoint through which requests for token metadata stored in Amazon S3 are handled. To get the tokenId from the prior step, you can either find it on <a href="https://rinkeby.etherscan.io/&quot; target="_blank" rel="noopener noreferrer">etherscan</a> or change the mint configuration to wait for minting full confirmation response (not recommended for production). Once you have the minted tokenId, use it with the following code to request the metadata URI:</p><p>Copy the response, which contains the metadata URI API endpoint concatenated with the token ID provided in the request, and save it in a notepad for later.</p><p>Note that in Solidity, the view methods to retrieve NFT balances and URIs can be called with the altered <code>msg.sender</code> property to retrieve URIs, balances, and so on. The <code>msg.sender</code> property sets the origin address for a given smart contract call or transaction.</p><h2>Sign the message</h2><p>Next, you use the Ethereum-compatible blockchain wallet via MetaMask that you used to mint the NFT in an earlier step to sign a message that verifies that you’re the owner of the NFT for which you’re requesting metadata for. With the React application running from the earlier setup steps, navigate to localhost:3000 in your web browser. Provide the token ID, metadata ID, and smart contract address of your NFT and choose <strong>Sign Message</strong>. This triggers a pop-up window from your MetaMask wallet that requires you to accept the signature request. When the request is complete, it generates a JSON signature output that can be used to verify your NFT ownership.</p><p><a href="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2022/09/20/DBBLOG-2232-image007.jpg&quot;&gt;&lt;img class="wp-image-24648 size-full aligncenter" src="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2022/09/20/DBBLOG-2232-image007.jpg&quot; alt="" width="500" height="580" /></a></p><h2>Call the API to retrieve the metadata info</h2><p>Finally, you can enter the URL for your metadata API (defined in <code>deploy.json</code>) to submit a request to retrieve the token metadata for the NFT. You use the message that was signed with your wallet in the prior step to prove ownership of the NFT and subsequently to authenticate your request for the token metadata via the custom Lambda authorizer that verifies the Ethereum signature you produced with your wallet.</p><p class="c4"><a href="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2022/09/20/DBBLOG-2232-image009.jpg&quot;&gt;&lt;img class="alignnone size-full wp-image-24649" src="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2022/09/20/DBBLOG-2232-image009.jpg&quot; alt="" width="500" height="405" /></a></p><h2>Security considerations</h2><p>Although the implementation outlined in this post is designed to be easily deployable by the reader, there are additional security considerations to be aware of in your own deployment, including but not limited to:</p><ul><li>Consider deploying your Lambda functions inside a VPC construct to define clear network boundaries and ease the process of auditing connectivity and access</li><li>Take special care in managing private keys, including Ethereum wallet private keys, and use a secrets manager or key management mechanism at all times for key storage and signing</li><li>Consider adding a dynamic challenge to the authorization phase as part of the signing request step to avoid replay attacks</li><li>During the deployment process, run <code>yarn audit</code> and <code>npm audit</code> commands to be aware of any possible vulnerabilities present in application dependencies</li></ul><h2>Clean up</h2><p>To avoid incurring future charges, delete the resources deployed throughout this post:</p><ol><li>Empty the S3 bucket that stores the underlying NFT metadata files.</li><li>Delete the <code>ethSystemKey</code> parameter from Parameter Store.</li><li>Finally, delete the deployed AWS SAM stack using the AWS SAM CLI:</li></ol><h2>Conclusion</h2><p>In this post, we presented a way to control access to the underlying metadata and content for an NFT via Ethereum signature verification. The solution utilizes a custom Lambda authorizer and Ethereum signatures to authorize access to NFT metadata stored in Amazon S3, allowing only the owner of that NFT on the Ethereum blockchain to see the content stored in Amazon S3. Protecting the content pertaining to a given NFT provides the owner improved control over the accessibility and distribution of that content and potentially protects the value of the NFT itself.</p><p>To learn more about building full-stack NFT applications on AWS, refer to <a href="https://aws.amazon.com/blogs/database/part-1-develop-a-full-stack-serverless-nft-application-with-amazon-managed-blockchain/&quot; target="_blank" rel="noopener noreferrer">Develop a Full Stack Serverless NFT Application with Amazon Managed Blockchain – Part 1</a>.</p><h3>About the authors</h3><p class="c5"><strong><a href="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2021/11/26/Forrest-Coyl.jpg&quot;&gt;&lt;img class="size-full wp-image-18597 alignleft" src="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2021/11/26/Forrest-Coyl.jpg&quot; alt="" width="100" height="114" /></a>Forrest Colyer</strong> is a blockchain specialist Solutions Architect at AWS. Through his experience with private blockchain solutions led by consortia and public blockchain use cases like NFTs and DeFi, Forrest helps enable customers to identify and implement high-impact blockchain solutions.</p><p class="c5"><a href="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2022/09/20/matan.png&quot;&gt;&lt;img class="size-full wp-image-24647 alignleft" src="https://d2908q01vomqb2.cloudfront.net/887309d048beef83ad3eabf2a79a64a389ab1c9f/2022/09/20/matan.png&quot; alt="" width="100" height="135" /></a><strong>Matan Zutta</strong> is a Solutions Architect Manager at AWS. He leads and mentors the next generation of architects to assist customers in building and operating their systems in the cloud. Having worked in software development and architecture for more than 15 years in a variety of fields, he has specific passion for emerging technologies and tackling challenging problems.</p>

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

NFT AWS Lambda Amazon S3 以太坊 签名 授权 元数据 安全
相关文章