ethereum - 如何使用智能合约在以太坊区块链上存储 IPFS 哈希?
问题描述
我正在开发一个 react + IPFS DAPP 并制作一个简单的宠物店应用程序。现在我刚刚在 remix 上创建智能合约并尝试它的功能正常工作,但我遇到了一个问题。
交易到 PetShop.generatePet 错误:错误编码参数:错误:无效的数组化值(argument="value",value="QmWmyoMoctfbAaiEs2G46gpeUmhqFRDW6KWo64y5r581Vz",code=INVALID_ARGUMENT,version=bytes/5.0.5)
每当我调用 generatePet 函数并传递 IPFS 哈希时,它都会返回上述错误。
合同宠物店
pragma solidity ^0.6.6;
import "https://github.com/MuhammadSajid404/ERC721-Token/blob/master/ERC721.sol";
contract PetShop is ERC721 {
uint256 public tokenId;
uint256 public prevOwnerTokenID;
mapping(uint256 => uint256) public priceMapping;
mapping(uint256 => bytes32) tokenIdToOffchainContentHash;
event PetGenerated(address, uint256, uint256, bytes32);
event BuyPet(uint256, address, address);
event SuccessfulEtherWithdrawal(uint256, address, bool);
constructor() public
ERC721("ShanBuilders", "SBRS")
{}
function generatePet(uint256 _petPrice, bytes32 contentHash) public returns(bool) {
require(msg.sender != address(0), "Please! Check back! Registeration should not be from zero address");
require(msg.sender == ownerA, "Only contract owner can generate more pets");
tokenId++;
require(tokenId <= 16, "More than 16 pets is not allowed");
priceMapping[tokenId] = _petPrice;
tokenIdToOffchainContentHash[tokenId] = contentHash;
_mint(ownerA, tokenId);
emit PetGenerated(ownerA, tokenId, _petPrice, contentHash);
return true;
}
function checkPrice(uint256 _tokenId) public view returns(uint256) {
return priceMapping[_tokenId];
}
function checkHashForAToken(uint256 _tokenId) public view returns(bytes32) {
return tokenIdToOffchainContentHash[_tokenId];
}
function buyPet(uint256 _tokenId) public payable returns(bool, string memory) {
prevOwnerTokenID = _tokenId;
address buyer = msg.sender;
address _owner = ownerOf(prevOwnerTokenID);
require(buyer != address(0), "Should not be zero address");
require(_exists(prevOwnerTokenID), "Invalid property Id, not registered");
require(msg.value == checkPrice(prevOwnerTokenID), "Please Send The Required Value");
withDraw(msg.value);
_transfer(_owner, buyer, prevOwnerTokenID);
emit BuyPet(_tokenId, _owner, buyer);
return (true, "Succesful");
}
function withDraw(uint256 _amount) public returns(bool) {
address _owner = ownerOf(prevOwnerTokenID);
require(_amount > 0, "Amount must be valid");
payable(_owner).transfer(_amount);
emit SuccessfulEtherWithdrawal(_amount, _owner, true);
return true;
}
}
注意:我更喜欢使用字节而不是字符串,因为它们消耗的气体比字符串少。如何解决这个问题,我在 stackoverflow 上看到了很多答案,但实际上我没有理解其中的任何一个。
解决方案
bytes32
对于 SHA-256 散列来说已经足够了,对于其他散列函数或可变长度的多散列格式可能还不够。
推荐阅读
- postgresql - 如何在 AWS RDS 的 Postgres 中创建只读用户?
- html - 如何在 iFrame 中包含 Bootstrap
- gulp - gulp 4 - 使用监视服务器作业而不是编译器作业
- git - 如何防止跳过 Git Hooks
- python - 如何确定用于回归或分类的特征?
- ruby-on-rails - 创建了 POST 路由,但导致 RoutingError(No Route 与 POST 匹配)
- html - 包含主导航的侧边栏的 ARIA 里程碑角色
- mongodb - 监视 Mongo db 的 Bash 脚本不起作用
- html - 我怎样才能摆脱顶部多余的空白?
- javascript - 如何在 Angular 中对嵌套的订阅方法进行单元测试?