## ERC777
* an ERC20-compatible interface
* transfer tokens using a send function, similar to ether transfers
* compatible with ERC820 for token contract registration
* allow contracts and addresses to control which tokens they send through a tokensToSend function that is called prior to sending
* enable contracts and addresses to be notified of the tokens' receipt by calling a tokensReceived function in the recipient, and to reduce the probability of tokens being locked into contracts by requiring contracts to provide a tokensReceived function
* allow existing contracts to use proxy contracts for the `tokensToSend and `tokensReceived` functions
* operate in the same way whether sending to a contract or an EOA
* provide specific events for the minting and burning of tokens
* enable operators (trusted third parties, intended to be verified contracts) to move tokens on behalf of a token holder
* provide metadata on token transfer transactions in userData and operatorData fields
---
### ERC777 contract interface specification
```
interface ERC777Token {
function name() public constant returns (string);
function symbol() public constant returns (string);
function totalSupply() public constant returns (uint256);
function granularity() public constant returns (uint256);
function balanceOf(address owner) public constant returns (uint256);
function send(address to, uint256 amount, bytes userData) public;
function authorizeOperator(address operator) public;
function revokeOperator(address operator) public;
function isOperatorFor(address operator, address tokenHolder)
public constant returns (bool);
function operatorSend(address from, address to, uint256 amount,
bytes userData,bytes operatorData) public;
event Sent(address indexed operator, address indexed from,
address indexed to, uint256 amount, bytes userData,
bytes operatorData);
event Minted(address indexed operator, address indexed to,
uint256 amount, bytes operatorData);
event Burned(address indexed operator, address indexed from,
uint256 amount, bytes userData, bytes operatorData);
event AuthorizedOperator(address indexed operator,
address indexed tokenHolder);
event RevokedOperator(address indexed operator, address indexed tokenHolder);
}
```