argotorg / argotorg/solidity

ABI does not contain sufficient information to compute the correct function selector

Open
#7,530 7 comments 0 reactions 0 assignees View on GitHub
bug :bug: protocol design :crystal_ball:
Dominant language
C++
Stars
25.7k
Forks
6.2k
Avg merge
1d 11h
Merged PRs (30d)
21

Description

## Description

The ABI does not contain sufficient information to compute the correct function selector for accessing the contract. More specifically, a `library` and a `contract` with the same entry points may have different 4 byte selectors, but nothing in the ABI allows to decide whether we are dealing with a contract or a libary.

A similar issue is raised in #7102, but there the conclusion is to put the information into the metadata, which does not the issue here. Possible solutions:

- Put a flag like `contractKind: contract` or `contractKind: library` into the ABI.
- For each function (and event?), add a field with the string that has to be hashed for the selector.
- Less preferably: for each function (and event?), add a field with the 4/32-byte selector.

## Environment

- Compiler version: 0.5.12
- Target EVM version (as per compiler settings): default
- Framework/IDE (e.g. Truffle or Remix): command line
- EVM execution environment / backend / blockchain client:
- Operating system: Linux

## Steps to Reproduce

The ABIs of the following two contracts are identical, but the selectors are different.
```
$ cat l.sol
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
library C {
struct S {address a;}
function F(S calldata) external pure returns (uint256) {return 0;}
}

$ solc --hashes --abi l.sol
[...]
Function signatures:
9b21e02d: F(C.S)
Contract JSON ABI
[{"constant":true,"inputs":[{"components":[{"internalType":"address","name":"a","type":"address"}],"internalType":"struct C.S","name":"","type":"tuple"}],"name":"F","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"}]
```
```
$ cat c.sol
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract C {
struct S {address a;}
function F(S calldata) external pure returns (uint256) {return 0;}
}

$ solc --hashes --abi c.sol
[...]
Function signatures:
a0b61132: F((address))
Contract JSON ABI
[{"constant":true,"inputs":[{"components":[{"internalType":"address","name":"a","type":"address"}],"internalType":"struct C.S","name":"","type":"tuple"}],"name":"F","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"}]
```

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the selector difference with l.sol and c.sol using solc --hashes --abi. Review the ABI design options in this issue and the related metadata discussion in #7102 before choosing a representation. Done means the emitted ABI lets consumers distinguish library and contract selectors, with coverage for both examples.

Written by the indexing model from the issue text.

Assessment

Tech stack
solidity
Domain
blockchain, compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.