web3.js是一个JavaScript API库。要让DApp在以太坊上运行,我们可以使用web3.js库提供的web3对象。web3.js通过RPC调用与本地节点通信,它可以与任何公开RPC层的以太坊节点一起使用。web3包含eth对象-web3.eth(用于与以太坊区块链交互)和shh对象-web3.shh(用于与Whisper交互)
dapp定制开发技术主要包括以太坊智能合约定制开发,包括智能合约语言Solidity开发,以太坊智能合约框架Truffle开发,Web3.js开发,以太坊区块链浏览器Mist开发等。这些技术可以帮助开发者快速构建出功能强大、可靠性高的dapp。
此外,dapp定制开发还涉及到以太坊智能合约测试、以太坊智能合约安全性测试、以太坊智能合约部署测试等。这些技术可以帮助开发者快速测试和部署dapp,从而确保dapp的可靠性和安全性。
数据作为新型生产要素,能为实体经济带来放大、叠加和倍增作用,是做强做优做大数字经济的关键。
建立数据可信流通体系,增强数据的可用、可信、可流通、可追溯水平,是激活数据要素潜能、赋能实体经济的重要途径。区块链技术具有去中心化、共识机制、不可篡改、可以追溯、规则透明等特点。
ERC-721的基础知识在这个Infura博客中有所介绍。我们选择使用ERC721URIStorage,这样就不必使用静态元数据文件来填充tokenURI。目前为止,我们导入了刚才自己创建的接口和OpenZeppelin的ERC721URIStorage实现,并让我们的ERC4907智能合约继承它们的属性,如下:
//SPDX-License-Identifier:MIT
pragma solidity>=0.4.22<0.9.0;
import"openzeppelin/contracts/token/ERC721/ERC721URIStorage.sol";
import"./IERC4907.sol";
contract ERC4907 is ERC721URIStorage,IERC4907{
constructor()public{
}
}
contract ERC4907 is ERC721,IERC4907{
constructor(string memory _name,string memory _symbol)ERC721(_name,_symbol){
}
}
contract ERC4907 is ERC721URIStorage,IERC4907{
struct UserInfo{
address user;//address of user role
uint64 expires;//unix timestamp,user expires
}
mapping(uint256=>UserInfo)internal _users;
///notice set the user and expires of a NFT
///dev The zero address indicates there is no user
///Throws iftokenId
is not valid NFT
///param user The new user of the NFT
///param expires UNIX timestamp,The new user could use the NFT before expires
function setUser(uint256 tokenId,address user,uint64 expires)public virtual override{
require(_isApprovedOrOwner(msg.sender,tokenId),"ERC721:transfer caller is not owner nor approved");
UserInfo storage info=_users[tokenId];
info.user=user;
info.expires=expires;
emit UpdateUser(tokenId,user,expires);
}
///notice Get the user address of an NFT
///dev The zero address indicates that there is no user or the user is expired
///param tokenId The NFT to get the user address for
///return The user address for this NFT
function userOf(uint256 tokenId)
public
view
virtual
override
returns(address)
{
if(uint256(_users[tokenId].expires)>=block.timestamp){
return _users[tokenId].user;
}else{
return address(0);
}
}