What is the correct implementation of ERC777 standard?

Does anyone know how to correctly implement the new ERC777 token standard? I’ve been trying to create an ERC777 contract (see code below) but keep struggling with a couple of things. According to the standard, recipient addresses must match the ITokenRecipientinterface as returned by an ERC-672 reverse lookup. Any idea how to do this? There seems to be a fallback interface ITokenFallback that is not mentioned in the standard at all. How does 777 handle fallbacks (e.g. in case foreign tokens are sent to the contract)? The standard requires the usage of operatorData and userData but doesn’t really say what to do with these values. Is it sufficient to include this data in the events that are defined in the 777 interface? My ERC777 implementation so far:

contract MyToken is EIP777 { string public name;

uint8 public decimals;

string public symbol;

uint256 public totalSupply;

mapping (address => uint256) balances;

mapping (address => mapping (address => bool)) authorizedOperators; function send(address _to, uint256 _value) returns (bool success) {

if (balances[msg.sender] >= _value && _value > 0) {

balances[msg.sender] -= _value;

balances[_to] += _value;

Send(msg.sender, _to, _value, msg.sender, null, null);

return true;

} else { return false; }

} function send(address _to, uint256 _value, _userData bytes) returns (bool success) {

if (balances[msg.sender] >= _value && _value > 0) {

balances[msg.sender] -= _value;

balances[_to] += _value;

Send(msg.sender, _to, _value, msg.sender, _userData, null);

return true;

} else { return false; }

} function operatorSend(address _from, address _to, uint256 _value, bytes _userData, bytes _operatorData) returns (bool success) {

if (balances[_from] >= _value && _value > 0 && isOperatorAuthorizedFor(msg.sender, _from) ) {

balances[_to] += _value;

balances[_from] -= _value;

Send(_from, _to, _value, msg.sender, _userData, _operatorData);

return true;

} else { return false; }

} function balanceOf(address _owner) constant returns (uint256 balance) {

return balances[_owner];

} function authorizeOperator(address _operator, bool _authorized) public {

authorizedOperators[msg.sender][_operator] = _authorized;

AuthorizeOperator(msg.sender, _operator, _authorized);

} function isOperatorAuthorizedFor(address _operator, address _tokenHoler) public constant returns (bool) {

return authorizedOperators[_tokenHoler][_operator];

} }

I did some research and stumbled upon YogaToken. However, it uses ERC672 and a more complex implementation of authorizedOperators which adds globallyAuthorizedOperators and a doSend() function. It doesn't implement ITokenRecipient , either.

Julien Marchard, Tech Lead @ ConsenSys Paris answered:

1. Matching the ERC777TokensRecipient interface is optional. More specifically, one single ERC1820 registry is deployed on most Ethereum networks, always at the same address: 0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24. The ERC1820 registry contains a mapping from addresses to contract addresses verifying the ERC777TokensRecipient interface. Those ERC777TokensRecipient contracts contain a tokensToSend and a tokensReceived hook functions. Every ERC777 transfer occurs in the following way:

Step1: If the sender address is registered in ERC1820 registry the tokensToSend hook function is executed. If the sender address is not registered, this step is skipped.

Step2: The sender and recipient balances are updated.

Step3: If the recipient address is registered in ERC1820 registry the tokensReceived hook function is executed. If the recipient address is not registered, this step is skipped. 2. There’s no fallback interface. 3. It is not specified in the standard, it depends on the implementation. The data field can contain information which will condition the validation/revert of the transaction depending on the business use case. For example, the implementation proposed by ConsenSys uses the data field to inject a certificate containing a signature of an authority verified on-chain thanks to an ecrecover operation.

ConsenSys Ireland developers answering questions on Ethereum Stack Exchange

How to compare hashes in Solidity

How does abi.encodePacked(…) and sha256(..) work in Solidity? I’m trying to implement a signature in a Solidity contract and I’m having problems when it comes to comparing hashes. I calculate the hash with the following code in solidity:

sha256(abi.encodePacked(param1, ...., paramN);

Where:

abi.encodePacked(param1, ..., paramN) = [bytes: 0x0102030405060701]

and

sha255(abi.encodePacked(param1, ..., paramN)) = [bytes32: 0x245138c905599c8579ab186fbdbd6e62396aac35a98a6568f8803eed049d1251]

The main problem I’m having is that by using python sha256 on 0102030405060701 the result I’m getting is 5bc31e3decf480124c79c114744d111ec82b62e466a097c3ced6fe76cbace9a5 What am I doing wrong?

Bruno Martins, Senior Software Engineer at ConsenSys Ireland answered: