使用 javascript 调用 solidity 智能合约来铸造代币似乎不起作用

Posted

技术标签:

【中文标题】使用 javascript 调用 solidity 智能合约来铸造代币似乎不起作用【英文标题】:Calling solidity smart contract with javascript to mint token does not seem to work 【发布时间】:2021-06-26 12:59:38 【问题描述】:

我有一个关于以太坊的新问题——刚刚开始并试图了解以太坊开发环境。

我有一个非常简单的 721 测试合约,我部署到 Ropsten,我可以使用 REMIX 来使用它,它可以用于铸造和查看代币余额 (tokenCounter) 等。

这是“合同”:https://ropsten.etherscan.io/address/0x97E0175415cB7D758cFB0ffc27Be727360664B90

// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
 
import "@0xcert/ethereum-erc721/src/contracts/tokens/nf-token-metadata.sol";
import "@0xcert/ethereum-erc721/src/contracts/ownership/ownable.sol";

contract Icollect is NFTokenMetadata, Ownable 
 
 uint256 public tokenCounter;

  constructor() NFTokenMetadata () 
    nftName = "Icollect";
    nftSymbol = "ICOL";
    tokenCounter = 0;
  
 
  function mint(string calldata _uri) external onlyOwner 
    super._mint(msg.sender, tokenCounter);
    super._setTokenUri(tokenCounter, _uri);
    tokenCounter = tokenCounter + 1;
  

当我使用此测试 javascript 和安全帽进行本地测试时,该合约似乎适用于铸造代币

async function main() 

    const contract_address = "0x5FbDB2315678afecb367f032d93F642f64180aa3";      
    const Icollect = await ethers.getContractFactory("Icollect");
    const icollect = await Icollect.attach(contract_address);

    const mint_return = await icollect.mint("https://test.test");    
    console.log("mint returned: ", mint_return);
    
    console.log("owner:", await icollect.owner());
    console.log("owner:", await icollect.ownerOf(0)); 
    console.log("symbol:", await icollect.symbol());
    console.log("URI:", await icollect.tokenURI(0));
    console.log("token counter:", await icollect.tokenCounter());    
  
  
  main()
    .then(() => process.exit(0))
    .catch(error => 
      console.error(error);
      process.exit(1);
    );
    

问题:当我尝试从网页铸造代币时,我似乎无法让“铸造”交易工作(当我需要 gas 时)。但是,查看变量是有效的(例如合同的名称和所有者)。知道我在这里做错了什么。

const transaction = contract.methods.mint(NFT_URI);

我正在构建对象,然后对其进行签名,然后将其发送。交易似乎有效,但我没有看到额外的令牌。

这是使用以下代码的示例“薄荷”交易之一:https://ropsten.etherscan.io/tx/0x6f3fc389355ffedfe135ac049837ac2d1a6eb6aad1dd10b055addfa70814e0fd 但是使用 REMIX 查询 'tokenCounter' 表明我从不增加计数。

document.getElementById('mintbutton').onclick = async function() 
        let NFT_URI = document.getElementById("nft_uri").value;                                            
        let contract_address = document.getElementById("contract_address").value;                                            
        const contract = await new web3.eth.Contract(abi, contract_address);  
        let account_address = document.getElementById("account_address").value;  
        const account = web3.eth.accounts.privateKeyToAccount(privateKey).address;        
        const transaction = contract.methods.mint(NFT_URI);
        let nonce_count = await web3.eth.getTransactionCount(account_address);        

        //build the transaction            
        const txObject = 
            nonce: nonce_count, 
            to: account_address,
            //value: web3.utils.toHex(21000),
            //gasLimit: web3.utils.toHex(1000000),
            gasPrice: web3.utils.toHex(web3.utils.toWei('10','gwei')),            
            gas: await transaction.estimateGas(from: account),
            data: transaction.encodeABI()
        ;

        const signed  = await web3.eth.accounts.signTransaction(txObject, privateKey);        
        const return_from_send = await web3.eth.sendSignedTransaction(signed.rawTransaction);
                        
        return_string = 
            "blockHash: " + return_from_send.blockHash + "<br>" +
            "blockNumber: <a href='https://ropsten.etherscan.io/block/"  + return_from_send.blockNumber + "'>" + return_from_send.blockNumber + "</a><br>" +
            "contractAddress: " + return_from_send.contractAddress + "<br>" +
            "cumulativeGasUsed: " + return_from_send.cumulativeGasUsed + "<br>" +            
            "from: <a href='https://ropsten.etherscan.io/address/" + return_from_send.from  + "'>" + return_from_send.from + "</a><br>" +
            "gasUsed: " + return_from_send.gasUsed + "<br>" +
            "status: " + return_from_send.status + "<br>" +
            "to:  <a href='https://ropsten.etherscan.io/address/" + return_from_send.to + "'>" + return_from_send.to + "</a><br>" +
            "transactionHash: <a href='https://ropsten.etherscan.io/tx/" + return_from_send.transactionHash + "'>" + return_from_send.transactionHash + "</a><br>" +
            "transactionIndex: " + return_from_send.transactionIndex + "<br>" +
            "type: " + return_from_send.type + "<br>"; 

        $('#mint_return').html(return_string);            
        
        var x = document.getElementById("showDIV3");        
        x.style.display = "block";

    

Patrick - 这是 console.log https://imgur.com/XBQTAxT 的链接

解决方案:我在交易对象中输入了错误的地址。我有帐户地址而不是合同地址。以下更正。

        //build the transaction            
        const txObject = 
            nonce: nonce_count, 
            to: contract_address, //NOT account_address,
            //value: web3.utils.toHex(21000),
            //gasLimit: web3.utils.toHex(1000000),
            gasPrice: web3.utils.toHex(web3.utils.toWei('10','gwei')),            
            gas: await transaction.estimateGas(from: account),
            data: transaction.encodeABI()
        ;

【问题讨论】:

I don't see the additional token. 您希望在哪里看到它?你为什么希望在那里看到它? 你能添加你的错误吗?控制台输出什么? 我建议你在 EtherScan 上验证你的合约源代码,然后在你的以太坊交易的符号输出中看到。然后您可以在 EtherScan 本身上看到它们更改的任何状态,这是非常强大的信息来源。 @MikkoOhtamaa - 谢谢你的建议。当我对创建令牌的 REMIX EtherScan 和创建令牌的 JavaScript 进行比较时,它清楚地表明我的是“SELF”,而 REMIX 是“OUT”。这导致我的交易对象的地址错误(我有 account_address 而不是 contract_address)。现在可以了。谢谢你的推荐。我没有意识到调试工具 EtherScan 会有多好 :-) 这是另一个公链交易调试工具tenderly.co 【参考方案1】:

解决方案:我在交易对象中输入了错误的地址。我有帐户地址而不是合同地址。以下更正。

//build the transaction            
    const txObject = 
        nonce: nonce_count, 
        to: contract_address, //NOT account_address,
        //value: web3.utils.toHex(21000),
        //gasLimit: web3.utils.toHex(1000000),
        gasPrice: web3.utils.toHex(web3.utils.toWei('10','gwei')),            
        gas: await transaction.estimateGas(from: account),
        data: transaction.encodeABI()
    ;

【讨论】:

以上是关于使用 javascript 调用 solidity 智能合约来铸造代币似乎不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在solidity 0.4.6中使用send()函数时合约抛出无效地址

Solidity知识点集 — Keccak256与事件(二)

使用 Web3 从 Solidity 调用函数

使用 truffle 在solidity 中调用函数时出现新的 BigNumber() 错误。如何修复错误?

solidity[1]-HelloWorld

使用 Python Web3.py 调用 Solidity 函数