以太卡标准] ERC20 系列、ERC721 系列、ERC1400 系列
1,摘要
【本文目标】
通过本文学习,了解ERC定义及知名ERC协议标准,如ERC20以及ERC223、ERC621,ERC777,ERC827,ERC1410协议; ERC721以及 ERC875,ERC1155,ERC998协议,ERC 865等描述和定义。
2,ERC的定义及标准列表
ERC代表“Ethereum Request for Comment",这是Ethereum版的意见征求稿 (RFC),RFC是由互联网工程任务组制定的一个概念。 RFC中的备忘录包含技术和组织注意事项。 对于ERC,意见征求稿中包括一些关于以太坊网络建设的技术指导。
ERC是Ethereum开发者为以太坊社区编写的。 因此,ERC的创建流程中包括开发人员。 为了创建一个以太坊平台的标准,开发人员应当提交了一个以太坊改进方案(EIP,Ethereum Improvement Protocol), 改进方案中包括协议规范和合约标准。 一旦EIP被委员会批准并最终确定,它就成为ERC。 EIP的完整原始信息可以在GITHUB网址找到。
EIP提案首先需要进行一个严格的验收进程,大致包括了以下四个步骤:
1)如果开发人员对软件改动有了新的想法,这个想法应该以拉取请求(pull request)的形式呈现出来。在一个拉取请求中,改动能够在提案中轻易完成,同时积极听取社区的反馈。在这里,它属于EIP编辑的审查改动范围内。
2)如果EIP编辑认为这个请求在技术上没有错误的地方,并且符合以太坊的社区价值观,他们会将其作为草稿合并到下一个阶段中。
3)在合并之后,如Geth何Parity等以太坊各式各样的软件应用才会诞生,并且如果它们能真的运作起来,这个提案最终被看作是“已接受”。
4) 一旦接受以后,整个平台就会根据这个EIP提供的用以运行以太坊软件的多样代码来进行升级。
相应的EIP对应有4种状态:
草稿(Draft) - 处于打开状态,便于考察讨论;
接受(Accepted) - 即将被接受,例如将包含在下一个硬分叉中;
定稿(Final)- 在上一个硬分叉中被接受,已定稿;
延期(Deferred)- 不会马上被接受,但也许在将来的硬分叉版本会考虑。
最终确定的EIP为以太坊开发者提供了一套可实施的标准。 这使得智能合约可以遵循这些通用的接口标准来构建。EIP的状态列表可以在https://eips.ethereum.org/all找到,它的主要分类见下图:
截止到目前,ERC家族Final可以用下图表示:
ERC-20是整个加密社区中最为人熟知的标准,在Ethereum平台之上发布的大多数通证(token)都使用它。
3,ERC20系列 - ERC20、ERC223、ERC621, ERC777,ERC827,ERC1400
3.1 ERC20标准
-
状态:
定稿(Final)
-
提交记录:
https://github.com/ethereum/EIPs/issues/20
-
标准说明:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
-
推荐样例:
https://github.com/OpenZeppelin/openzeppelin-solidity/tree/master/contracts/token/ERC20
定稿(Final)
https://github.com/ethereum/EIPs/issues/20
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
https://github.com/OpenZeppelin/openzeppelin-solidity/tree/master/contracts/token/ERC20
ERC-20标准中定义了以下函数接口:
-
totalSupply():
返回代币供给总量 -
balanceOf(address _owner):
返回_owner的帐户余额 -
transfer(address _to,uint256 _value):
并将数量为_value的代币转入地址_to并触发transfer事件 -
transferFrom(address _from,address _to,uint256_value):
将地址_from中的_value数量的代币转入地址_to ,并触发transfer事件 -
approve(address _spender,uint256 _value):
允许_spender提取限额_value的代币 -
allowance(address _owner,address _spender):
返回_spender可从_owner提款的代币数量上限
ERC-20于2015年提出并于2017年9月正式实施。这是代币标准化的一个很好的起点。 然而,开发者社区 已经注意到它存在一些缺陷和漏洞,此外,还有一些场景它不能很好的满足。因此陆续提出了其他的ERC标准。
3.2 ERC223
-
状态:
草稿(Draft) -
提交记录:
https://github.com/ethereum/EIPs/issues/223 -
标准说明:
https://github.com/Dexaran/ERC223-token-standard -
推荐样例:
https://github.com/Dexaran/ERC223-token-standard/tree/Recommended
开发人员Dexaran在一篇文章中详细描述了ERC20不适合的两种场景:
“在ERC20中执行交易有两种方式:transfer函数,approve + transferFrom机制,通证余额只是通证合约中的一个变量。
通证的交易是合约内部变量的变化。 转出账户的余额将减少,转入账户的余额将增加。
交易发生时, transfer()函数不会通知转入账户。 因此转入账户将无法识别传入的交易! 我写了一个例子,可以展示这一导致未处理的交易和资金损失的过程 。
因此,如果接收账户是合约账户,那么必须使用approve + transferFrom机制来发送通证。
如果接受账户是外部帐户,则必须通过transfer函数发送通证。 如果选择了错误的机制,通证将卡在合约内(合约将不会识别交易),没有办法来提取这些卡壳的通证。“
他对这个问题提出的解决方案包含在ERC-223中 。 它与ERC-20标准非常相似,但解决了上述问题。当通证转移到智能合约账户时,该合约的特殊函数tokenFallback() 允许接收方合约拒绝通证或触发进一步的操作。 大多数情况下,这可以用来代替approve()函数。
函数接口:
transfer(address _to, uint _value):
会区分代币是发往外部账户地址还是发往智能合约地址。
transfer(address _to, uint _value, bytes _data):
会区分代币是发往外部账户地址还是发往智能合约地址,还可以传送数据。
- 1、如果_to是合约,则此函数必须传输通证并调_to中的函数tokenFallback(address,uint256,bytes)。
- 2、如果_to(接收方合约)中没有实现tokenFallback函数,则事务必须失败,并且不会发生通证的传输。
- 3、如果_to是外部拥有的地址,则必须发送事务,而不尝试在_to中执行tokenFallback。
- 4、_data可以附加到这个通证(token)交易中,它将永远保持在块状(需要更多的gas)。 _data可以是空的。
注意:检查_to是合约还是地址的推荐方法是组装_to的代码。 如果_to中没有代码,那么这是一个外部拥有的地址,否则就是一个合约。
//assemble the given address bytecode. If bytecode exists then the _addr is a contract.
function isContract(address _addr) private view returns (bool is_contract) {
uint length;
assembly {
//retrieve the size of the code on target address, this needs assembly
length := extcodesize(_addr)
}
return (length>0);
}
function tokenFallback(address _from, uint _value, bytes _data)
_from是通证(token)发送者,_value是传入通证(token)的数量,_data是附加的数据,类似于Ether事务中的数据。 适用于以太交易的回退功能,并且不返回任何内容。
tokenFallback -- 通证(token)持有者发送通证(token)时处理从通证(token)合约所调用的通证(token)传输的功能
注意:msg.sender将是tokenFallback函数内的通证(token)合约。 过滤哪些通证(token)(通过通证(token)契约地址)发送可能很重要。 通证(token)发送者(谁发起了代币交易的人)在_from thetokenFallback函数内。
示例代码:
ERC223_Interface.sol
pragma solidity ^0.4.9;
/* 新的 ERC23 contract 接口文件 */
contract ERC223 {
uint public totalSupply;
function balanceOf(address who) constant returns (uint);
function name() constant returns (string _name);
function symbol() constant returns (string _symbol);
function decimals() constant returns (uint8 _decimals);
function totalSupply() constant returns (uint256 _supply);
function transfer(address to, uint value) returns (bool ok);
function transfer(address to, uint value, bytes data) returns (bool ok);
function transfer(address to, uint value, bytes data, string custom_fallback) returns (bool ok);
event Transfer(address indexed from, address indexed to, uint value, bytes indexed data);
}
Receiver_Interface.sol
pragma solidity ^0.4.9;
/*
* Contract that is working with ERC223 tokens
*/
contract ContractReceiver {
struct TKN {
address sender; //调用合约的人
uint value;
bytes data;
bytes4 sig; //签名
}
function tokenFallback(address _from, uint _value, bytes _data){
TKN memory tkn;
tkn.sender = _from;
tkn.value = _value;
tkn.data = _data;
uint32 u = uint32(_data[3]) + (uint32(_data[2]) << 8) + (uint32(_data[1]) << 16) + (uint32(_data[0]) << 24);
tkn.sig = bytes4(u);
/* tkn变量是Ether交易的msg变量的模拟
* tkn.sender是发起这个通证(token)交易的人(类似于msg.sender)
* tkn.value发送的通证(token)数(msg.value的类比)
* tkn.data是通证(token)交易的数据(类似于msg.data)
* tkn.sig是4字节的功能签名
* 如果通证(token)事务的数据是一个函数执行
*/
}
}
ERC223_Token.sol
pragma solidity ^0.4.9;
import "./Receiver_Interface.sol";
import "./ERC223_Interface.sol";
/**
* ERC23 token by Dexaran
*
* https://github.com/Dexaran/ERC23-tokens
* https://github.com/LykkeCity/EthereumApiDotNetCore/blob/master/src/ContractBuilder/contracts/token/SafeMath.sol
*/
contract SafeMath {
uint256 constant public MAX_UINT256 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
function safeAdd(uint256 x, uint256 y) constant internal returns (uint256 z) {
if (x > MAX_UINT256 - y) throw;
return x + y;
}
function safeSub(uint256 x, uint256 y) constant internal returns (uint256 z) {
if (x < y) throw;
return x - y;
}
function safeMul(uint256 x, uint256 y) constant internal returns (uint256 z) {
if (y == 0) return 0;
if (x > MAX_UINT256 / y) throw;
return x * y;
}
}
//示例的智能合约代码
contract ERC223Token is ERC223, SafeMath {
mapping(address => uint) balances;
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
// 获取token的名称
function name() constant returns (string _name) {
return name;
}
// 获取token的符号
function symbol() constant returns (string _symbol) {
return symbol;
}
// 获取token精确到小数点后的位数
function decimals() constant returns (uint8 _decimals) {
return decimals;
}
// 获取token的发布总量
function totalSupply() constant returns (uint256 _totalSupply) {
return totalSupply;
}
// 当用户或其他合约想要转移资金时调用的功能。
function transfer(address _to, uint _value, bytes _data, string _custom_fallback) returns (bool success) {
//如果to是合约
if(isContract(_to)) {
if (balanceOf(msg.sender) < _value) throw; //如果当前的余额不够就抛出
balances[msg.sender] = safeSub(balanceOf(msg.sender), _value);//发送者的余额做减法
balances[_to] = safeAdd(balanceOf(_to), _value); //接收者的余额做加法
ContractReceiver receiver = ContractReceiver(_to); //初始化接收合约,构造函数参数为接收者的合约地址
receiver.call.value(0)(bytes4(sha3(_custom_fallback)), msg.sender, _value, _data);
Transfer(msg.sender, _to, _value, _data);
return true;
}
else {
return transferToAddress(_to, _value, _data);
}
}
// 当用户或其他合约想要转移资金时调用的功能。
function transfer(address _to, uint _value, bytes _data) returns (bool success) {
if(isContract(_to)) {
return transferToContract(_to, _value, _data);
}
else {
return transferToAddress(_to, _value, _data);
}
}
// 类似于ERC20传输的标准功能传输,没有_data。
// 由于向后兼容性原因而增加。
function transfer(address _to, uint _value) returns (bool success) {
//类似于没有_data的ERC20传输的标准功能传输
//由于向后兼容性原因而增加
bytes memory empty;
if(isContract(_to)) {//如果是合约
return transferToContract(_to, _value, empty);
}
else {
return transferToAddress(_to, _value, empty);
}
}
//组装定地址字节码。 如果存在字节码,那么_addr是一个合约。
function isContract(address _addr) private returns (bool is_contract) {
uint length;
assembly {
//检索目标地址上的代码大小,这需要汇编
length := extcodesize(_addr)
}
return (length>0);
}
//当传递目标是一个地址时调用函数
function transferToAddress(address _to, uint _value, bytes _data) private returns (bool success) {
if (balanceOf(msg.sender) < _value) throw;
balances[msg.sender] = safeSub(balanceOf(msg.sender), _value);
balances[_to] = safeAdd(balanceOf(_to), _value);
Transfer(msg.sender, _to, _value, _data);
return true;
}
//当传递目标是一个合约时调用函数
function transferToContract(address _to, uint _value, bytes _data) private returns (bool success) {
if (balanceOf(msg.sender) < _value) throw;
balances[msg.sender] = safeSub(balanceOf(msg.sender), _value);
balances[_to] = safeAdd(balanceOf(_to), _value);
ContractReceiver receiver = ContractReceiver(_to);
receiver.tokenFallback(msg.sender, _value, _data); //必须要调用这个回调
Transfer(msg.sender, _to, _value, _data);
return true;
}
//得到_owner的余额
function balanceOf(address _owner) constant returns (uint balance) {
return balances[_owner];
}
}
3.3 ERC621
状态:
草稿(Draft)提交记录:
https://github.com/ethereum/EIPs/issues/621标准说明:
推荐样例:
https://github.com/skmgoldin/EIP621Token/blob/master/contracts/EIP621Token.sol
ERC-621是ERC-20标准的扩展。 它增加了两个额外的功能, increaseSupply和decreaseSupply 。这可以增加和减少流通中的通证(token)供应。 ERC-20只允许单一的通证发放事件。 这将供应量限制在一个固定的不可改变的数目。 ERC-621建议totalSupply应当是可修改的。
接口函数说明:
increaseSupply(uint value, address to):
可以给特定账户to
增加value
值的供应量,代币总供应量totalSupply
也同步增加;
decreaseSupply(uint value, address from):
可以给特定账户to
减少value
值的账户余额,代币总供应余额totalSupply
也同步减少;
3.4 ERC777
状态:
草稿(Draft)提交记录:
https://github.com/ethereum/EIPs/issues/777标准说明:
https://eips.ethereum.org/EIPS/eip-777推荐样例:
https://github.com/jacquesd/ERC777/tree/devel/contracts
功能描述
本标准用于提升ERC20标准的使用范围。这个标准的主要优点有:
- 可以同使用Ether一样的原理使用ERC777通证,通证发送采用函数
send(dest, value, data)
的。 - 不管是合约还是常规的地址都可以控制和拒绝那些通过注册
tokensToSend
钩函数发送的通证(通过在钩函数内部执行reverting回滚函数触发拒绝。) - 不管是合约还是常规的地址都可以控制和拒绝那些通过注册
tokensToSend
钩函数接收的通证(通过在钩函数内部执行reverting回滚函数触发拒绝。) -
tokensReceived
勾函数运行发送通证给一个合约,并在一次交易中通知完成,不像ERC20需要2次通知(approve
/transferFrom
) 才能达到相同效果。 - 通证持有者可以“授权”和“撤销”可以代表他们发送通证的操作员。这些操作员用于验证合约,如交易所,支票处理器或自动收费系统。
- 每次通证交易都包含一个“data”字节字段和一个类似的“operatorData”,可以*地用于将数据传递给接收方。
- 通过部署实现钱包的“tokensReceived”钩子的代理合约,它与不包含“tokensReceived”钩子功能的钱包向后兼容。
协议代码
interface ERC777Token {
function name() public view returns (string);
function symbol() public view returns (string);
function totalSupply() public view returns (uint256);
function balanceOf(address owner) public view returns (uint256);
function granularity() public view returns (uint256);
function defaultOperators() public view returns (address[]);
function authorizeOperator(address operator) public;
function revokeOperator(address operator) public;
function isOperatorFor(address operator, address tokenHolder) public view returns (bool);
function send(address to, uint256 amount, bytes data) public;
function operatorSend(address from, address to, uint256 amount, bytes data, bytes operatorData) public;
function burn(uint256 amount, bytes data) public;
function operatorBurn(address from, uint256 amount, bytes data, bytes operatorData) public;
event Sent(
address indexed operator,
address indexed from,
address indexed to,
uint256 amount,
bytes data,
bytes operatorData
);
event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
event Burned(address indexed operator, address indexed from, uint256 amount, bytes operatorData);
event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
event RevokedOperator(address indexed operator, address indexed tokenHolder);
}
3.5 ERC827
状态:
草稿(Draft)提交记录:
https://github.com/ethereum/EIPs/issues/827标准说明:
推荐样例:
https://github.com/windingtree/erc827/blob/master/contracts/ERC827/ERC827Token.sol
它允许转让通证并允许持有人允许第三方使用通证。 以太坊上的通证可以被其他应用程序重复使用,这其中也包括钱包和交易所。 当需要支持第三方动态消费限额调整时这一点非常有用。
该标准目前处于草稿状态,并被证明有使用安全风险,建议暂不使用。
4,ERC721系列
4.1 ERC721
-
状态:
定稿(Final)
-
提交记录:
https://github.com/ethereum/EIPs/issues/721
-
标准说明:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-
推荐样例:
1)https://www.cryptokitties.co/
2)https://github.com/OpenZeppelin/openzeppelin-solidity/tree/master/contracts/token/ERC721
-
状态:
定稿(Final) -
提交记录:
https://github.com/ethereum/EIPs/issues/721 -
标准说明:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md -
推荐样例:
1)https://www.cryptokitties.co/
2)https://github.com/OpenZeppelin/openzeppelin-solidity/tree/master/contracts/token/ERC721
ERC-721与ERC-20和ERC-223都大不相同。 它描述了一个不可互换的通证,官方简要解释是Non-Fungible Tokens,简写为NFTs,多翻译为非同质代币。 这意味着每个通证是完全不同的,并且每个通证对不同的用户都有不同的价值。 理解这种通证的一个方法就是回忆CryptoKittes。 每一个数字猫都是独立的,其价值取决于其稀缺性和用户的购买欲。
ERC-721通证(token)可用于任何交易所,但通证价值是“每个通证的唯一性和稀缺性所决定的结果”。标准中规定的接口函数包括name、symbol、totalSupply、balanceOf、ownerOf、approve、takeOwnership 、 transfer 、tokenOfOwnerByIndex和tokenMetadata 。 它还定义了两个事件: Transfer和Approval 。 Gerald Nash的 这篇文章很好地解释了可互换性的概念。
函数接口说明:
-
balanceOf(address _owner):
返回由_owner 持有的NFTs的数量。 -
ownerOf(uint256 _tokenId):
返回tokenId代币持有者的地址。 -
exists(uint256 _tokenId):
tokenId代币是否存在,返回BOOL值; -
approve(address _to, uint256 _tokenId):
授予地址_to具有_tokenId的控制权,方法成功后需触发Approval 事件。 -
getApproved(uint256 _tokenId):
获得_tokenId授权的地址; -
setApprovalForAll(address _operator, bool _approved):
授予地址_operator具有所有NFTs的控制权,成功后需触发ApprovalForAll事件。 -
isApprovedForAll(address _owner, address _operator):
用来查询授权。 -
transferFrom(address _from, address _to, uint256 _tokenId)
不建议使用本函数,建议使用safeTransferFrom函数。 -
safeTransferFrom(address _from, address _to, uint256 _tokenId):
把_tokenId
代币从_from
账户安全转移到_to
账户,安全是指如果目标地址为合约地址,则执行onERC721Received
进行资产转移,否则的话交易会回滚;如果目标地址为外部账号地址,则正常转移。
更深度分析的文章参考《【基于ERC721的区块链游戏】迷恋猫从玩耍到开发》。
4.2 ERC875
状态:
还处于pull request下(issue)
提交记录:
https://github.com/ethereum/EIPs/issues/875
标准说明:
推荐样例:
https://github.com/alpha-wallet/ERC875-Example
状态:
还处于pull request下(issue)
提交记录:
https://github.com/ethereum/EIPs/issues/875
标准说明:
推荐样例:
https://github.com/alpha-wallet/ERC875-Example
AlphaWallet自主开发了ERC875协议族。该协议不仅会让数字资产变得具有收藏价值,同时也能帮助现实世界中不可拆分替代、具有物权唯一性的资产上链,这就能为线下服务的链上操作提供了可能性。
虽然另一种协议ERC721也能实现token的不可置换性,但其存在需要交易双方支付gas费用、无法简单实现原子化交易等一些不易于用户使用的问题。
ERC875内置了两个密码学协议, 一方面能够简单实现原子化交易(atomic swap)——直接搭建去中心化市场、降低普通用户使用门槛,卖家无需持有以太币,买家支付一次gas即能完成;另外一方面可以简单打包处理大量交易。
拿基于ERC721的加密猫来说,换用ERC875协议的话,能够实现。用户在商家网站法币购猫,通过MagicLink免费把猫导入用户的钱包,之后用户还可以在不需要持有以太币的情况下,通过MagicLink把猫售出或者免费转让,全部过程都是无中心的原子化交易。另外商家可以一次批发100只猫给分销商。
接口函数或者变量说明
- totalTickets:
- inventory:
- ticketIndex:
- expiryTimeStamp:
- owner:
- admin:
- transferFee:
- numOfTransfers:
- name:
- symbol:
- decimals:
-
Token(uint256[] numberOfTokens, string evName,uint expiry, string eventSymbol, address adminAddr):
构建函数,样例如example: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], "MJ comeback", 1603152000, "MJC", "0x007bEe82BDd9e866b2bd114780a47f2261C684E3"] -
getDecimals():
返回代币的小数点后位数值; -
trade(uint256 expiry,uint256[] tokenIndices,uint8 v,bytes32 r,bytes32 s):
交易函数,例如:0, [3, 4], 27, "0x2C011885E2D8FF02F813A4CB83EC51E1BFD5A7848B3B3400AE746FB08ADCFBFB", "0x21E80BAD65535DA1D692B4CEE3E740CD3282CCDC0174D4CF1E2F70483A6F4EB2" - encodeMessage(bytes12 prefix, uint value,uint expiry, uint256[] tokenIndices):
-
name():
返回代币名称; -
symbol():
返回代币表示; -
getAmountTransferred():
返回已传输的数量; -
isContractExpired():
合约是否过期; -
balanceOf(address _owner):
返回账户余额; - myBalance():
-
transfer(address _to, uint256[] tokenIndices):
资产转账; - transferFrom(address _from, address _to, uint256[] tokenIndices):
-
endContract():
结束合约; -
getContractAddress():
获取合约地址;
4.3 ERC998
状态:
草稿(Draft)
提交记录:
https://github.com/ethereum/EIPs/issues/998
标准说明:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-998.md
推荐样例:
https://github.com/mattlockyer/composables-998
状态:
草稿(Draft)
提交记录:
https://github.com/ethereum/EIPs/issues/998
标准说明:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-998.md
推荐样例:
https://github.com/mattlockyer/composables-998
不同的ERC代币可以被兼容的ERC-998代币既代表一组相似资产(ERC-20代币),一种独特资产的分类(ERC-721代币),或者内嵌于单比交易的混合体。
这个协议是以不可以替代代币为基础的全新复杂型数字资产。一个ERC-998代币可以作为一个数字资产投资组合。
中心资产和辅助资产的结合
第一个使用案例是可以和不同数字资产和零件结合外加附加增值功能的中心NFT币。增值可以通过个人花费时间和精力,或者购买来实现。
在奢侈品行业里,这些可以作为应用于不同时尚品牌的“外表”和“包装”。 比如说,中心的不可替代货币是外表,可以辅助鞋子和钱包,每一个都代表了他们自己的NFT。这一整个套装都作为一部分组合到ERC-998代币里面。
单一资产的几个组成部分
作为附加债券的一部分,单一的数字资产可以被ERC-998代币群组所代表。因为每一个部分都是由自己的NFT被独特的体现出来的,NFT代币组合可以保证货品的绝对真实性。然而,除非依附于实际商品的形式,每一个NFT都没有自己的价值。这是一个可以附加在类似手表,珠宝这样价值商品上的非常强势的防伪手段。
上图所示为劳力士的三个组件,每个组件都有一个单独的序列号 - 表壳、表面和指针。单独来看,这些部件几乎没有任何价值,但它们一起构成了一个真正的劳力士手表,由一个ERC-998代币所代表。
分组集合
通常被认为是组合的任何东西,例如一副牌,一本历史邮票或罕见的硬币收集等,可以在一个组合型代币下结合在一起。因此,完整的组合可以由单个数字资产表示。
大多数奢侈品牌都有很大众的产品,每年都会使用重新设计的型号,这些产品往往成为收藏品。在奢侈品战略下,消费者购买经典和品牌,这些都是通过多年来产品的演变出来的。作为上图中的示例,该品牌在三年内发布了其第一、二、三代模型,这些模型被分组为一个组合代币。
同时,这也更为品牌加强与老客户的联系。例如,如果用户可以通过Smart-Links这样可组合的代币,显示他们对某个品牌的所有收藏品,那么该品牌将能够通过独家邀请和优惠来奖励这位客户。
4.4 ERC1155
状态:
草稿(Draft)
提交记录:
https://github.com/ethereum/EIPs/issues/1155
标准说明:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1155.md
推荐样例:
https://enjincoin.io/
状态:
草稿(Draft)
提交记录:
https://github.com/ethereum/EIPs/issues/1155
标准说明:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1155.md
推荐样例:
https://enjincoin.io/
ERC-1155是一种定义token的新标准,1155是这种方法的编号。1155标准定义了一种解决上述问题的新方法。现在『物品』(可能包含ERC20的token或ERC721的token或两者都有)可以被单一的一个合约(打包处理)来定义了。合约里包含区别token们所需的最小量的数据。合约的状态包含了每个token ID的配置信息和管理收集的所有行为。ERC-1155的灵活性更强,它使得开发者可以自行选择是批量生成某一种特定的token,还是构建不可被复制的惟一元数据。
ERC-1155支持原子交换,“原子交换”是指不通过中介物而将一种token换成为另外一种token。
ERC-1155的最大进步就是可以融合不同token(可能是“可替换”的代币与“不可替换”的代币的混合体)进行“打包处理”。
函数接口说明:
name(uint256 _itemId):
symbol(uint256 _itemId):
decimals(uint256 _itemId):
totalSupply(uint256 _itemId):
balanceOf(uint256 _itemId, address _owner):
allowance(uint256 _itemId, address _owner, address _spender):
transfer(uint256[] _itemId, address[] _to, uint256[] _value):
transferFrom(uint256[] _itemId, address[] _from, address[] _to, uint256[] _value):
approve(uint256[] _itemId, address[] _spender, uint256[] _value):
increaseApproval(uint256[] _itemId, address[] _spender, uint256[] _addedValue):
decreaseApproval(uint256[] _itemId, address[] _spender, uint256[] _subtractedValue):
ownerOf(uint256 _itemId):
itemURI(uint256 _itemId):
itemByIndex(uint256 _itemId, uint256 _index):
itemOfOwnerByIndex(uint256 _itemId, address _owner, uint256 _index):
4.5,ERC1190
-
状态:
还处于pull request下(issue)
-
提交记录:
https://github.com/ethereum/EIPs/issues/1190
-
标准说明:
-
推荐样例:
ERC1190的token将使每个数字对象的创建者(如艺术品或游戏中的物品)在每次使用该对象时会自动受益,无论是下一秒还是几年之后。
还处于pull request下(issue)
https://github.com/ethereum/EIPs/issues/1190
ERC1190的token将使每个数字对象的创建者(如艺术品或游戏中的物品)在每次使用该对象时会自动受益,无论是下一秒还是几年之后。
每位ERC1190 token的持证者都可以单独持有“创造权”或“所有权”,当然也可以同时持有两个权利。
ERC1190的三种获益方式:
1.销售“所有权”;
2.销售“创造权”;
3.在固定时间内出租“所有权”。
一个数字产品的“所有权”持有者和“创造权”持有者通过以上三种方式都会自动获得一定收益。
1. 创造者将拥有“创造权”和“所有权”
我们以网络游戏中的“装备”为例。
物品的创建者可以将物品及其所有权信息嵌入到一个ERC1190 token中。
简单来说,我在游戏里制造了一把剑并把他命名为“裂魂之剑”。
身为创造者的我就会拥有他的“创造权”和“所有权”。
如果我想销售我的“裂魂之剑”那么它的“所有权”将会被转交给一个第三方参与者(此处我们将他定为玩家A),但是我还会保留它的“创造权”。
在这次销售中,我一次性获得了“所有权”带来的收益,并会在将来的某个时刻获得一定比例的“所有权”收益。
2. 如果“所有权”持有者再次发生转换,创造者将会获得收益
拥有“裂魂之剑”“所有权”的玩家可以永久持有该装备,在游戏里如果这件装备得到了更好的优化或者其他玩家因为某种原因喜欢上了这件装备,那么它的价格也必定会有所提高。
当玩家A决定销售“裂魂之剑”的“所有权”给玩家B时,他会从中获得高比例的收益,而拥有“创造权”的我将会获得低比例的收益。
如:10%。(这个比例会在一开始设计该token的时候写在协议上)每一次“所有权”的转换,“创造权”持有者都会自动获得售价10%的收益。
3. 如果“所有权”持有者出租了“装备”,那么创造者也可以获得一定比例的租金
如果玩家B暂时不需要使用“裂魂之剑”。
他便有权将“装备”出租给玩家C。按照规定,做为创造者的我将会获得租金里的10%,而这个过程也是可以无限循环的(任何一次有关“装备”权益的转换都需要支付给创造者一定比例的费用)。
其实不单单是在游戏领域,在其它的的虚拟领域都可以进行这一活动,如影音,艺术等。人们不用再担心复杂的交易流程和版权费问题了。
规则被写入了智能合约,基于区块链技术,双方的任何行为都会自动触发后续动作。
4. 创造者销售“创造权”
身为创造者的我有权出售“裂魂之剑”的“创造权”,并且我将会一次性的拿到所有收益,这其中的收益比销售“所有权”所带来的收益要高得多。
之后,新的“创造权”持有者在未来的“权益”转换过程中会重复上面的步骤,只要他不出售自己的“创造权”,他将继续重复获得租金或“所有权”转换所带来的收益。
用一个现实世界的例子“房屋”来解释,你拥有它的房产证并且拥有它的出租权,使用权。
你作为房产证的拥有者可以将房子的使用权出售给客人A,而客人A可以选择将他的使用权卖给客人B或者将使用权出租给客人B。
而你依旧可以获得一定比例的房租收益或售卖分红,且最终房屋还是归你所有。
当你卖掉了房产证之后才会从这个利益关系中彻底退出,之后任何的“权益”转换也就和你没有半毛钱关系!
函数接口:
function approve(address[] owners, uint royaltyForOwnershipTransfer, uint royaltyForRental) returns uint256;
说明:Function to initialize token and set the owner(s) and the royalty rates. Returns the unique token ID for the digital asset.function transferCreativeLicense(address[] creativeLicenseHolders, address[] newOwners, uint256 tokenId);
说明: Function to transfer creative license of token。function transferOwnershipLicense(address[] creativeLicenseHolders, address[] ownershipLicenseHolders, address newOwners[], uint256 tokenId);
说明:Function to transfer ownership license of tokenfunction rentAsset(address[] creativeLicenseHolders, address[] ownershipLicenseHolders, address[] renters, uint256 tokenId);
说明:Function to rent asset
5 STO标准相关
5.1 ERC1400(ERC1410,ERC1411)
状态:
草稿(Draft)提交记录:
1)ERC 1410: Partially Fungible Token Standard:
https://github.com/ethereum/EIPs/issues/1410
2)ERC 1400: Security Token Standard #1411
https://github.com/ethereum/EIPs/issues/1411标准说明
推荐样例:
https://blog.neufund.org/good-protocols-how-to-properly-standardize-security-tokens-95ff83c81c4a
标准说明
该标准由 Gosselin, Adam Dossa, Pablo Ruiz 和 F* Vogelsteller 撰写。其中 Gosselin 和 Dossa 为 Polymath 工作,而 Ruiz 拥有国际商业和金融背景,而 Dossa 是以太坊开发人员和网页设计师。团队经验互补,有一定的实力。
ERC1410 (等同ERC1411)将 ERC20/ERC777 中不存在解释属性的余额,附加额外的信息,从而划分成不同的部分,就可以做一些操作上的限制。
而 ERC1400 (等同ERC1411)是对 ERC1410 标准的继承和改进。
无论是 ERC20 还是 ERC777,每个单位的 Token 都是相同的,并无附加属性,属于 fungible token(同质化代币/可互换 Token)。ERC721标准的 Token,每个 Token 均有不同的ID,不同ID可以有不同的解释,属于 no-fungible token(非同质化 Token,不可互换 Token)。
ERC1410标准的 Token 属于Partially-Fungible Token (部分可互换 Token ),将 ERC20/ERC777 中不存在解释属性的余额,附加额外的信息,从而划分成不同的部分,就可以做一些操作上的限制(例如:某些操作只限定于指定 tranche 的 Token,某些操作优先消耗指定tranche的 Token)。
ERC1400 则是继承 ERC1410 标准,增加了证券相关业务会使用到的函数:证券增发,相关法律文件存储等。
先前一些证券型 Token 的合约大多是在 ERC20 标准的基础上,通过维护一个或多个以太坊地址集合,对这部分地址做出了划分:是否通过kyc,是否处于锁定期等,来进行转账上的限制。这些都是在地址层面做出不同的解释。而 ERC1400 对 Token 本身做了不同解释,以适用于更复杂的证券相关业务场景。
关于ERC20,以及其它ERC成员的关系,可见下图:
函数接口说明
/// @title ERC-1410 Partially Fungible Token Standard
/// @dev See https://github.com/SecurityTokenStandard/EIP-Spec
interface IERC1410 is IERC777 {
// Token Information
function balanceOfByTranche(bytes32 _tranche, address _tokenHolder) external view returns (uint256);
function tranchesOf(address _tokenHolder) external view returns (bytes32[]);
// Token Transfers
function sendByTranche(bytes32 _tranche, address _to, uint256 _amount, bytes _data) external returns (bytes32);
function sendByTranches(bytes32[] _tranches, address _to, uint256[] _amounts, bytes _data) external returns (bytes32[]);
function operatorSendByTranche(bytes32 _tranche, address _from, address _to, uint256 _amount, bytes _data, bytes _operatorData) external returns (bytes32);
function operatorSendByTranches(bytes32[] _tranches, address _from, address _to, uint256[] _amounts, bytes _data, bytes _operatorData) external returns (bytes32[]);
// Default Tranche Management
function getDefaultTranches(address _tokenHolder) external view returns (bytes32[]);
function setDefaultTranche(bytes32[] _tranches) external;
// Operators
function defaultOperatorsByTranche(bytes32 _tranche) external view returns (address[]);
function authorizeOperatorByTranche(bytes32 _tranche, address _operator) external;
function revokeOperatorByTranche(bytes32 _tranche, address _operator) external;
function isOperatorForTranche(bytes32 _tranche, address _operator, address _tokenHolder) external view returns (bool);
// Transfer Events
event SentByTranche(
bytes32 indexed fromTranche,
address operator,
address indexed from,
address indexed to,
uint256 amount,
bytes data,
bytes operatorData
);
event ChangedTranche(
bytes32 indexed fromTranche,
bytes32 indexed toTranche,
uint256 amount,
);
// Operator Events
event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
event RevokedOperator(address indexed operator, address indexed tokenHolder);
event AuthorizedOperatorByTranche(bytes32 indexed tranche, address indexed operator, address indexed tokenHolder);
event RevokedOperatorByTranche(bytes32 indexed tranche, address indexed operator, address indexed tokenHolder);
}
/// @title IERCST Security Token Standard (EIP 1400)
/// @dev See https://github.com/SecurityTokenStandard/EIP-Spec
interface IERCST is IERCPFT {
// Document Management
function getDocument(bytes32 _name) external view returns (string, bytes32);
function setDocument(bytes32 _name, string _uri, bytes32 _documentHash) external;
// Controller Operation
function isControllable() external view returns (bool);
// Token Issuance
function isIssuable() external view returns (bool);
function issueByTranche(bytes32 _tranche, address _tokenHolder, uint256 _amount, bytes _data) external;
event IssuedByTranche(bytes32 indexed tranche, address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
// Token Redemption
function redeemByTranche(bytes32 _tranche, uint256 _amount, bytes _data) external;
function operatorRedeemByTranche(bytes32 _tranche, address _tokenHolder, uint256 _amount, bytes _operatorData) external;
event RedeemedByTranche(bytes32 indexed tranche, address indexed operator, address indexed from, uint256 amount, bytes operatorData);
// Transfer Validity
function canSend(address _from, address _to, bytes32 _tranche, uint256 _amount, bytes _data) external view returns (byte, bytes32, bytes32);
}
5.2 ERC1404
-
状态:
草稿(Draft) -
提交记录:
https://github.com/ethereum/EIPs/issues/1404
ERC-1404是由TokenSoft工程团队提出的通证标准,其设计目的就是为证券通证、通证化证券以及其它携带复杂要求的其它通证而准备的。
根据介绍,ERC-1404具有ERC-20通证标准的所有优点,例如,易于部署以及与以太坊网络的可互操作性。此外,该标准还提供了一些关键的改进,允许发行者实施监管性转让限制。
ERC1404在ERC20的基础上增加2个函数。
contract ERC1404 is ERC20 {
function detectTransferRestriction (address from, address to, uint256 value) public view returns (uint8);
function messageForTransferRestriction (uint8 restrictionCode) public view returns (string);
}
函数说明:
detectTransferRestriction:此函数是发行者强制执行通证传输的限制逻辑。例子包括,(1)检查通证接收者是否在白名单内,(2)检查发送者的通证是否在锁定期内被冻结等等。该函数实现仅面向发行者,另外,第三方可以公开调用该函数来检查转移的预期结果。因为这个函数会返回一个uint8代码,所以它允许函数调用者知道传输失败的原因,并将其报告给相关的对方。
messageForTransferRestriction:这个函数实际上是一个“消息”访问器,它负责以人类可阅读的方式解释一笔交易为什么会被限制。通过规范消息查找,开发者授权用户界面构建器,有效地向用户报告错误。
5.3 ERC1594
状态:
草稿(Draft)提交记录:
https://github.com/ethereum/EIPs/issues/1594标准说明:
推荐样例:
说明文档
参考《通往STO之路|ERC-1594标准详解》了解相关中文翻译。
6,ERC865
状态:
还处于pull request下(issue)
提交记录:
https://github.com/ethereum/EIPs/issues/865
标准说明:
推荐样例:
https://github.com/lavawallet/lava-wallet
状态:
还处于pull request下(issue)
提交记录:
https://github.com/ethereum/EIPs/issues/865
标准说明:
推荐样例:
https://github.com/lavawallet/lava-wallet
以太坊开发者Bhaskar Sharma在Medium网站上发表了一篇文章,提出了一个在以太坊中使用对用户更友好的代币的提案,这一提案将允许用户来采用去中心化应用程序(DApps)时使用代币(tokens)来支付交易费用,而不是用以太币ETH来支付。
他认为,以太坊区块链中的费用支付问题为新手带来了麻烦,这些费用用于支付矿工将交易打包到区块并确保区块链的安全。用户必须认识以太坊的工作原理,这样才能理解燃料(gas)价格和成本。用户还需要获得必要的以太币来支付这两种费用。
函数接口说明:
transferPreSigned(bytes _signature, address _to, uint256 _value, uint256 _gasPrice, uint256 _nonce):
approvePreSigned(bytes _signature, address _spender, uint256 _value, uint256 _gasPrice, uint256 _nonce):
**approveAndCallPreSigned(bytes _signature, address _spender, uint256 _value, bytes _extraData, uint256 _gasPrice, uint256 _nonce) **:
increaseApprovalPreSigned(bytes _signature, address _to, uint256 _amount, uint256 _gasPrice, uint256 _nonce):
decreaseApprovalPreSigned(bytes _signature, address _to, uint256 _amount, uint256 _gasPrice, uint256 _nonce):
revokeSignature(bytes _signature):
7. 其他ERC协议
7.1 ERC165
-
状态:
已定稿(Final)
-
提交记录:
https://github.com/ethereum/EIPs/issues/165
-
标准说明:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
-
状态:
已定稿(Final) -
提交记录:
https://github.com/ethereum/EIPs/issues/165 -
标准说明:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
ERC165定义以下功能:
1) 如何识别接口;
2) 一个智能合约如何发布它执行的接口;
3) 如何检测一个智能合约是否执行了ERC-165协议;
4) 如何检测一个智能合约是否执行了一个给定的接口;
8,参考
(1)以太坊官网ERC列表
(2)以太坊官网EIP提出列表
推荐阅读
-
以太卡标准] ERC20 系列、ERC721 系列、ERC1400 系列
-
41 个下载免费 3D 模型的最佳网站-使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 17. Clara.io Clara.io 是一个创建 3D 内容的全球平台,也是一个培养新 3D 艺术家的社区。Clara.io 提供+100,000个免费的3D模型,包括OBJ,Blend,STL,FBX,DAE,Babylon.JS,Three.JS格式,用于 Clara.io,Unity 3D,Blender,Sketchup,Cinema 4D,3DS Max和Maya。 使用说明:免费,标准和专业帐户仅供个人使用,如果您需要将 clara.io 用于商业用途,请与销售团队联系。 18. 3DExport 3DExport是一个市场,您可以在其中购买和销售用于CG项目的3D模型,3D打印模型和纹理。它提供15 +不同的3D格式供下载,如3DS MAX(.max),Cinema4D(.c4d),Maya(.mb,.ma),Lightwave(.lwo),Softimage(.xsi),Wavefront OBJ(.obj),Autodesk FBX(.fbx)等。它还提供15种不同的语言! 使用说明:免费下载仅供个人和非商业用途。 19. 3D Warehouse 3D Warehouse是一个开放的库,允许用户共享和下载SketchUp 3D模型,用于建筑,设计,施工和娱乐!任何人都可以免费制作,修改和重新上传内容到3D仓库,您可以找到任何您能想到的东西,如家具,电子产品,室内产品等。 使用说明:3D Warehouse中的所有模型都是免费的,因此任何人都可以下载文件以用于SketchUp甚至其他软件,如AutoCAD,Revit和ArchiCAD。 20. CadNav.com CadNav是CGI平面设计师和CAD / CAM / CAE工程师的在线3D模型库,我们提供超过50000 +免费3D模型和CAD模型下载。在CadNav网站上,您可以下载高质量的多边形网格3D模型,3D CAD实体对象,纹理,Vray材料,3D作品,CAD图纸等。 使用说明:免费下载仅供个人和非商业用途。 21. All3dfree.net 就像网站名称一样,它提供免费的3D模型,还包括Vray材料,CAD块,2d和3d纹理集合,无需注册即可免费下载。它是不断更新的,因此您可以查找或请求3DS,MAX,C4D,skp,OBJ,FBX,MTL等格式的模型。 使用说明:所有资源均不允许用于商业用途,否则您将承担责任。 22. Hum3D 自2005年以来,Hum3D帮助来自3多个国家的80D艺术家节省3D建模时间,并制作逼真的3D模型,用于电影,视频游戏,AR应用程序和可视化。所有模型均由首席3D艺术家进行验证,他们检查其是否符合专业要求和最新的3D建模标准。 使用说明:免费下载仅供个人和非商业用途。 23. Artist-3D.com 艺术家-3D 库存的免费 3D 模型下载按通用类别排序。它为人体解剖学、汽车、家具、火箭、卫星等模型提供 AutoDesk 3DS Max 格式。您还可以在浏览他们的网站时找到教程和类似类型的建模。 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 24. Free the models 就像本网站的标题一样,它为3d应用程序和3d游戏引擎提供免费的内容模型。您可以为您的任何项目找到许多有趣且有用的模型!它提供3ds,wavefront,bryce,poser,lightwave,md2和unity3d格式的模型。还有一个很棒的纹理集合,可以在您最喜欢的建模和渲染程序中使用。 使用说明:您从这里下载的所有内容都可以免费使用,除非它不能包含在另一个免费的网络或CD收藏中,也不能单独出售。否则,您可以在商业游戏,3D应用程序或渲染作品中使用它。您不必提供信用,但如果您这样做,那就太好了。 25. Resources.blogscopia 本网站由一家名为Scopia的公司创建。他们制作3D图像和视频,您可以找到许多为CGI工作的信息架构设计的模型,所有这些都可以在现实生活中使用。您可以免费下载它们,但是,如果您想一次下载它们,您可以支付 3 到 9 欧元。 使用说明:您可以免费下载模型部分的所有文件。每个压缩文件都包含您也可以在此处找到的许可证。基本上,您可以对文件执行任何操作。唯一的限制是不归属于Scopia的重新分发。 26.ambientCG 1000+公共领域PBR材料适合所有人!环境CG是使用许多不同的方法和资产类型创建的,例如照片纹理(PBR),贴花(PBR),图集(PBR),照片纹理(普通),物质存档(SBSAR),雕刻画笔,3D模型和地形。您可以在所有项目中*使用它们! 使用说明:在 ambientCG 上提供下载的所有 PBR 材料、画笔、照片和 3D 模型均根据知识共享 CC0 1.0 通用许可提供。您可以复制、修改、分发和执行作品,即使是出于商业目的,也无需征得许可。信用将不胜感激。 不要满足于平庸的大理石纹理 - 立即使用我们的免费PBR大理石纹理升级您的3D设计。 27.Pixar One Twenty Eight 这是一个提供官方动画行业经典纹理的网站:皮克斯,创建于 1993 年,该纹理库包括 128 个重复纹理,现在免费提供。 它包含您来到的纹理,包括砖块和动物毛皮。肯定会有一些你可以使用的东西。 使用说明:皮克斯动画工作室的《Pixar One Twenty Eight》根据知识共享署名4.0国际许可协议进行许可。即使出于商业目的,您也可以重新混合、调整和构建您的作品,只要您以相同的条款对新创作进行信用和许可。 访问数以千计的免费纹理并提升您的设计游戏 - 立即开始下载! 28. 3DXO 即使有近 620 个免费贴纸可供下载,3DXO 也不是最大的资源,但它的内容非常有用,不需要注册。无论是简单的墙壁或地板,还是一些奇怪的小东西,您都需要的纹理都可以在此网站上看到。 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 29. 3DModelsCC0 3DModelsCC0 与其他产品的不同之处在于它包含超过 250+ 个高质量 3D 模型,并且本网站上的所有内容都是免费的,完全是公共领域!使用我们的模型时无需信用或归属! 使用说明:为每个人提供完全免费的公共领域内容。 30.Sketch up texture club Sketchup Texture Club是一个非营利性的教育和信息门户网站,由3D社区的图像促进协会管理,特别强调面向学生和建筑和室内设计专业人士的可视化和渲染技术,以及所有正在学习3D可视化的人。 使用说明:您无需支付版税或使用费。纹理可以免费下载和使用。不允许将纹理作为竞争产品出售或重新分发,即使图像被修改也是如此。 31. FlippedNormals FlippedNormal 是一个提供计算机图形和 3D 资产的市场,您可以找到许多用于雕刻、建模、纹理、概念艺术、3D 模型、游戏资产或课程的高级资产! 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 32. NASA 3D NASA 3D网站是一个在线门户,提供与太空和各种NASA任务相关的大量三维模型和模拟。该网站是用户友好的,并提供有关每个型号的详细信息。该网站允许用户探索和下载几种不同格式的模型,包括 OBJ、STL 和 FBX,只需单击下载按钮即可。 使用说明: 要下载模型,只需单击模型页面上的下载按钮并选择所需的格式。 33. 3DAGOGO (Astroprint) 3DAGOGO 是一个提供广泛 3D 模型的网站,包括角色、车辆和建筑物。3DAGOGO 的独特功能之一是它专注于适合 3D 打印的模型,使其成为希望创建物理原型或模型的设计师的绝佳资源。要使用 3DAGOGO,设计师只需在网站上搜索他们正在寻找的模型类型,然后下载 STL 格式的文件。 使用说明: 要使用 3DAGOGO,只需搜索所需的 3D 模型类型并下载 STL 格式的文件。根据需要自定义模型,并确保在将其用于商业目的之前检查使用权限。 34. FreeCAD FreeCAD是一款了不起的3D建模软件,可让您在计算机上创建令人难以置信的3D设计。该软件可免费下载和使用,它提供了广泛的工具和功能,可用于创建用于各种目的的3D模型。 该网站易于浏览,您可以找到开始使用FreeCAD的所有必要信息。此外,该网站还提供一系列教程和指南,可帮助您了解 3D 建模的来龙去脉。 使用说明: 要下载模型,请访问网站并从库中选择所需的模型。该网站还提供了一系列使用该软件的教程和指南。 35. Pinshape Pinshape是一个提供一系列3D打印模型的网站。网站上提供的型号质量很高,因此您可以确保您的最终印刷产品看起来很棒。该网站提供了广泛的模型,包括从家居用品到小雕像和珠宝的所有物品。 但这还不是Pinshape所能提供的全部!该网站还允许用户上传和共享自己的3D模型。这意味着您不仅可以下载出色的模型,还可以通过分享自己的设计为社区做出贡献。此外,Pinshape 提供了一系列自定义选项,因此您可以调整和调整模型以满足您的特定需求。 使用说明: 要下载模型,请在网站上创建一个帐户,搜索所需的模型,然后单击下载按钮。该网站还为每种型号提供了一系列定制选项。 36.Yeggi Yeggi 提供了大量免费的 3D 模型,您可以下载各种格式的模型,例如 STL、OBJ 和 FBX。该网站易于使用,您可以按关键字、类别或特定网站搜索模型。 Yeggi 对于任何寻找 3D 模型的人来说都是一个很好的资源。它提供了大量的模型集合,从日常物品到复杂的机械,以及介于两者之间的一切。该网站的收藏量在不断增长,每天都有新的型号增加。 使用说明: 要下载模型,请在网站上搜索所需的模型,然后单击下载按钮。该网站还提供指向托管模型的原始网站的链接。 37. Open3DModel 来自开放3D模型的图像 Open3DModel具有各种类别的模型,包括建筑,车辆和角色。无论您需要建筑物,汽车还是人的3D模型,都可以在此网站上找到。 该网站易于浏览,您可以按类别或关键字搜索模型。每个模型都附带预览图像和详细信息,例如文件格式、大小和多边形数量。此信息可以帮助您选择适合您需求的模型。 使用说明: 要下载模型,请访问网站,从库中选择所需的模型,然后单击下载按钮。 使用最好的 3D 资产管理工具简化您的 3D 制作流程。立即试用它们,将您的 3D 项目提升到一个新的水平! 38. 3DExport 对于那些为其 3D 设计项目寻找 3D 模型、纹理和其他资源的人来说,该平台是一个很好的资源。该网站有大量模型可供选择,包括 3D 打印对象、游戏资产等。用户可以按类别、文件格式或价格范围浏览,以找到适合其项目的完美资源。此外,3DExport 还提供一系列教程和其他 3D 资源,以帮助用户提高技能并创建更令人印象深刻的设计。 使用说明: 要使用 3DExport,只需创建一个帐户并浏览可用型号。您可以按类别、格式和价格进行搜索,以找到所需的型号。找到喜欢的模型后,只需下载它并开始在您的项目中使用它。 39.Blend Swap Blend Swap是一个社区驱动的市场,提供与Blender软件兼容的各种免费3D模型。该平台允许用户共享和下载模型、纹理和其他资产,以便在他们的项目中使用。 使用说明: 创建免费帐户后,您可以浏览社区上传的大量3D模型。当您找到要使用的一个时,只需下载它并将其导入您选择的 3D 软件即可。 40. 3DShook 3DShook 是一个高级 3D 模型市场,提供一系列用于建筑、游戏等各个行业的高质量模型。该平台提供基于订阅的模型,具有不同的定价计划,允许用户访问一系列模型。 使用说明: 注册免费帐户后,只需浏览3D模型库,选择您喜欢的模型,然后以您需要的格式下载它们。 41. Smithsonian X 3D 史密森尼 X 3D 对于正在寻找历史文物和文物的高质量 3D 模型的设计师来说,这是一个独特的资源。该平台提供了大量3D模型,这些模型是根据史密森尼博物馆和研究中心中的真实物体扫描创建的。 使用说明: