智能合约已在各种区块链网络中得以实施,其中主要的依然是比特币和以太坊。虽然比特币网络以使用比特币执行交易闻名,它的协议也可以用来创建智能合约。
以太坊则是目前为止最引人注目的智能合约框架,因为它是专门为支持智能合约的使用创建的。用Solidity语言编程,以太坊智能合约框架有助于促进去中心化网络,便于用智能合约处理交易。
除了加密货币之外,在不同行业的也有用户场景,例如选举、供应链优化、电子商务中可有效利用智能合约。
pragma solidity 0.5.0;
// File: src/erc777/IERC777.sol
/**
* @dev Interface of the ERC777Token standard as defined in the EIP.
*
* This contract uses the
* [ERC1820 registry standard]() to let
* token holders and recipients react to token movements by using setting implementers
* for the associated interfaces in said registry. See `IERC1820Registry` and
* `ERC1820Implementer`.
*/
interface IERC777 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the smallest part of the token that is not divisible. This
* means all token operations (creation, movement and destruction) must have
* amounts that are a multiple of this number.
*
* For most token contracts, this value will equal 1.
*/
function granularity() external view returns (uint256);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by an account (`owner`).
*/
function balanceOf(address owner) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* If send or receive hooks are registered for the caller and `recipient`,
* the corresponding functions will be called with `data` and empty
* `operatorData`. See `IERC777Sender` and `IERC777Recipient`.
*
* Emits a `Sent` event.
*
* Requirements
*
* - the caller must have at least `amount` tokens.
* - `recipient` cannot be the zero address.
* - if `recipient` is a contract, it must implement the `tokensReceived`
* interface.
*/
function send(address recipient, uint256 amount, bytes calldata data) external;
/**
* @dev Destroys `amount` tokens from the caller's account, reducing the
* total supply.
*
* If a send hook is registered for the caller, the corresponding function
* will be called with `data` and empty `operatorData`. See `IERC777Sender`.
*
* Emits a `Burned` event.
*
* Requirements
*
* - the caller must have at least `amount` tokens.
*/
function burn(uint256 amount, bytes calldata data) external;
/**
* @dev Returns true if an account is an operator of `tokenHolder`.
* Operators can send and burn tokens on behalf of their owners. All
* accounts are their own operator.
*
* See `operatorSend` and `operatorBurn`.
*/
function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
/**
* @dev Make an account an operator of the caller.
*
* See `isOperatorFor`.
*
* Emits an `AuthorizedOperator` event.
*
* Requirements
*
* - `operator` cannot be calling address.
*/
function authorizeOperator(address operator) external;
/**
* @dev Make an account an operator of the caller.
*
* See `isOperatorFor` and `defaultOperators`.
*
* Emits a `RevokedOperator` event.
*
* Requirements
*
* - `operator` cannot be calling address.
*/
function revokeOperator(address operator) external;
/**
* @dev Returns the list of default operators. These accounts are operators
* for all token holders, even if `authorizeOperator` was never called on
* them.
*
* This list is immutable, but individual holders may revoke these via
* `revokeOperator`, in which case `isOperatorFor` will return false.
*/
function defaultOperators() external view returns (address[] memory);
/**
* @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
* be an operator of `sender`.
*
* If send or receive hooks are registered for `sender` and `recipient`,
* the corresponding functions will be called with `data` and
* `operatorData`. See `IERC777Sender` and `IERC777Recipient`.
*
* Emits a `Sent` event.
*
* Requirements
*
* - `sender` cannot be the zero address.
* - `sender` must have at least `amount` tokens.
* - the caller must be an operator for `sender`.
* - `recipient` cannot be the zero address.
* - if `recipient` is a contract, it must implement the `tokensReceived`
* interface.
*/
function operatorSend(
address sender,
address recipient,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external;
/**
* @dev Destoys `amount` tokens from `account`, reducing the total supply.
* The caller must be an operator of `account`.
*
* If a send hook is registered for `account`, the corresponding function
* will be called with `data` and `operatorData`. See `IERC777Sender`.
*
* Emits a `Burned` event.
*
* Requirements
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
* - the caller must be an operator for `account`.
*/
function operatorBurn(
address account,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external;
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 data, bytes operatorData);
event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
event RevokedOperator(address indexed operator, address indexed tokenHolder);
}
// File: src/erc777/IERC777Recipient.sol
/**
* @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.
*
* Accounts can be notified of `IERC777` tokens being sent to them by having a
* contract implement this interface (contract holders can be their own
* implementer) and registering it on the
* [ERC1820 global registry]().
*
* See `IERC1820Registry` and `ERC1820Implementer`.
*/
interface IERC777Recipient {
/**
* @dev Called by an `IERC777` token contract whenever tokens are being
* moved or created into a registered account (`to`). The type of operation
* is conveyed by `from` being the zero address or not.
*
* This call occurs _after_ the token contract's state is updated, so
* `IERC777.balanceOf`, etc., can be used to query the post-operation state.
*
* This function may revert to prevent the operation from being executed.
*/
function tokensReceived(
address operator,
address from,
address to,
uint amount,
bytes calldata userData,
bytes calldata operatorData
) external;
}
// File: src/erc777/IERC777Sender.sol
/**
* @dev Interface of the ERC777TokensSender standard as defined in the EIP.
*
* `IERC777` Token holders can be notified of operations performed on their
* tokens by having a contract implement this interface (contract holders can be
* their own implementer) and registering it on the
* [ERC1820 global registry]().
*
* See `IERC1820Registry` and `ERC1820Implementer`.
*/
interface IERC777Sender {
/**
* @dev Called by an `IERC777` token contract whenever a registered holder's
* (`from`) tokens are about to be moved or destroyed. The type of operation
* is conveyed by `to` being the zero address or not.
*
* This call occurs _before_ the token contract's state is updated, so
* `IERC777.balanceOf`, etc., can be used to query the pre-operation state.
*
* This function may revert to prevent the operation from being executed.
*/
function tokensToSend(
address operator,
address from,
address to,
uint amount,
bytes calldata userData,
bytes calldata operatorData
) external;
}