sbt-ethereum 0.5.3

sbt-ethereum v0.5.3 has been released!

As Ethereum smart contracts have grown more complex, and chains other than the Ethereum mainchain have grown more important, importing ABIs into sbt-ethereum has become a bit of a pain.

sbt-ethereum keeps a database of all the ABIs it has encountered, and lets you associate those ABIs with smart contracts on a temporary or permanent basis. But to “encounter” an ABI, sbt-ethereum must either generate the ABI itself via compilation, or import it from elsewhere.

For the Ethereum mainchain, sbt-ethereum has long been able to download ABIs of verified contracts from Etherscan, if you set up an API key. If you don’t have an Etherscan API key set up, or for contracts not available on Etherscan, users had to paste in the literal ABI JSON, in compact format, i.e. not “pretty-printed” with embedded newlines.

But smart contracts have grown complicated, and ABIs can be very long and complex. Sometimes they are only avaliable in pretty-printed form, so users had to paste them into a “minifier” before they could paste them into sbt-ethereum. It got to be annoying.

sbt-ethereum v0.5.3 now permits users to paste in a file path or URL containing the importable ABI. Ideally, the file or URL is clean JSON, but if it is not, sbt-ethereum will try to “scrape” an ABI from the source. If it finds a unique, non-empty, “strict” ABI, it will offer to import it. (See the documentation, Importing Contract ABIs.)

This takes away almost all the pain from ABI importing. Just cut and paste the URL of a trustworthy source:

> ethContractAbiImport 0x1C232F01118CB8B424793ae03F870aa7D0ac7f77
To import an ABI, you may provide the JSON ABI directly, or else a file path or URL from which the ABI can be downloaded.
Contract ABI or Source: https://blockscout.com/poa/xdai/address/0x1C232F01118CB8B424793ae03F870aa7D0ac7f77/contracts
[info] Attempting to interactively import a contract ABI.
[info] Checking to see if you have provided a JSON array or object directly.
[info] The provided text does not appear to be a JSON ABI.
[info] Checking if the provided source exists as a File.
[info] No file found. Checking if the provided source is interpretable as a URL.
[info] Interpreted user-provided source as a URL. Attempting to fetch contents.
We can attempt to SCRAPE a unique ABI from the text of the provided source.
Be sure you trust 'https://blockscout.com/poa/xdai/address/0x1C232F01118CB8B424793ae03F870aa7D0ac7f77/contracts' to contain a reliable representation of the ABI.
Scrape for the ABI? [y/n] y
[info] No ABI was discovered in the raw bytes downloaded from 'https://blockscout.com/poa/xdai/address/0x1C232F01118CB8B424793ae03F870aa7D0ac7f77/contracts'.
[info] Retrying, after unescaping as HTML.
[info] We had to scrape, but we were able to recover a unique ABI from source 'https://blockscout.com/poa/xdai/address/0x1C232F01118CB8B424793ae03F870aa7D0ac7f77/contracts'!
Ready to import the following ABI:
[ {
  "type" : "constructor",
  "stateMutability" : "nonpayable",
  "inputs" : [ {
    "type" : "address",
    "name" : "_factory",
    "internalType" : "address"
  }, {
    "type" : "address",
    "name" : "_WETH",
    "internalType" : "address"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "view",
  "outputs" : [ {
    "type" : "address",
    "name" : "",
    "internalType" : "address"
  } ],
  "name" : "WETH",
  "inputs" : [ ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ {
    "type" : "uint256",
    "name" : "amountA",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountB",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "liquidity",
    "internalType" : "uint256"
  } ],
  "name" : "addLiquidity",
  "inputs" : [ {
    "type" : "address",
    "name" : "tokenA",
    "internalType" : "address"
  }, {
    "type" : "address",
    "name" : "tokenB",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "amountADesired",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountBDesired",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountAMin",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountBMin",
    "internalType" : "uint256"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "payable",
  "outputs" : [ {
    "type" : "uint256",
    "name" : "amountToken",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountETH",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "liquidity",
    "internalType" : "uint256"
  } ],
  "name" : "addLiquidityETH",
  "inputs" : [ {
    "type" : "address",
    "name" : "token",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "amountTokenDesired",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountTokenMin",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountETHMin",
    "internalType" : "uint256"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "view",
  "outputs" : [ {
    "type" : "address",
    "name" : "",
    "internalType" : "address"
  } ],
  "name" : "factory",
  "inputs" : [ ]
}, {
  "type" : "function",
  "stateMutability" : "pure",
  "outputs" : [ {
    "type" : "uint256",
    "name" : "amountIn",
    "internalType" : "uint256"
  } ],
  "name" : "getAmountIn",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountOut",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "reserveIn",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "reserveOut",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "pure",
  "outputs" : [ {
    "type" : "uint256",
    "name" : "amountOut",
    "internalType" : "uint256"
  } ],
  "name" : "getAmountOut",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountIn",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "reserveIn",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "reserveOut",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "view",
  "outputs" : [ {
    "type" : "uint256[]",
    "name" : "amounts",
    "internalType" : "uint256[]"
  } ],
  "name" : "getAmountsIn",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountOut",
    "internalType" : "uint256"
  }, {
    "type" : "address[]",
    "name" : "path",
    "internalType" : "address[]"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "view",
  "outputs" : [ {
    "type" : "uint256[]",
    "name" : "amounts",
    "internalType" : "uint256[]"
  } ],
  "name" : "getAmountsOut",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountIn",
    "internalType" : "uint256"
  }, {
    "type" : "address[]",
    "name" : "path",
    "internalType" : "address[]"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "pure",
  "outputs" : [ {
    "type" : "uint256",
    "name" : "amountB",
    "internalType" : "uint256"
  } ],
  "name" : "quote",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountA",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "reserveA",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "reserveB",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ {
    "type" : "uint256",
    "name" : "amountA",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountB",
    "internalType" : "uint256"
  } ],
  "name" : "removeLiquidity",
  "inputs" : [ {
    "type" : "address",
    "name" : "tokenA",
    "internalType" : "address"
  }, {
    "type" : "address",
    "name" : "tokenB",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "liquidity",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountAMin",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountBMin",
    "internalType" : "uint256"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ {
    "type" : "uint256",
    "name" : "amountToken",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountETH",
    "internalType" : "uint256"
  } ],
  "name" : "removeLiquidityETH",
  "inputs" : [ {
    "type" : "address",
    "name" : "token",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "liquidity",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountTokenMin",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountETHMin",
    "internalType" : "uint256"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ {
    "type" : "uint256",
    "name" : "amountETH",
    "internalType" : "uint256"
  } ],
  "name" : "removeLiquidityETHSupportingFeeOnTransferTokens",
  "inputs" : [ {
    "type" : "address",
    "name" : "token",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "liquidity",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountTokenMin",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountETHMin",
    "internalType" : "uint256"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ {
    "type" : "uint256",
    "name" : "amountToken",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountETH",
    "internalType" : "uint256"
  } ],
  "name" : "removeLiquidityETHWithPermit",
  "inputs" : [ {
    "type" : "address",
    "name" : "token",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "liquidity",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountTokenMin",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountETHMin",
    "internalType" : "uint256"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  }, {
    "type" : "bool",
    "name" : "approveMax",
    "internalType" : "bool"
  }, {
    "type" : "uint8",
    "name" : "v",
    "internalType" : "uint8"
  }, {
    "type" : "bytes32",
    "name" : "r",
    "internalType" : "bytes32"
  }, {
    "type" : "bytes32",
    "name" : "s",
    "internalType" : "bytes32"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ {
    "type" : "uint256",
    "name" : "amountETH",
    "internalType" : "uint256"
  } ],
  "name" : "removeLiquidityETHWithPermitSupportingFeeOnTransferTokens",
  "inputs" : [ {
    "type" : "address",
    "name" : "token",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "liquidity",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountTokenMin",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountETHMin",
    "internalType" : "uint256"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  }, {
    "type" : "bool",
    "name" : "approveMax",
    "internalType" : "bool"
  }, {
    "type" : "uint8",
    "name" : "v",
    "internalType" : "uint8"
  }, {
    "type" : "bytes32",
    "name" : "r",
    "internalType" : "bytes32"
  }, {
    "type" : "bytes32",
    "name" : "s",
    "internalType" : "bytes32"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ {
    "type" : "uint256",
    "name" : "amountA",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountB",
    "internalType" : "uint256"
  } ],
  "name" : "removeLiquidityWithPermit",
  "inputs" : [ {
    "type" : "address",
    "name" : "tokenA",
    "internalType" : "address"
  }, {
    "type" : "address",
    "name" : "tokenB",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "liquidity",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountAMin",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountBMin",
    "internalType" : "uint256"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  }, {
    "type" : "bool",
    "name" : "approveMax",
    "internalType" : "bool"
  }, {
    "type" : "uint8",
    "name" : "v",
    "internalType" : "uint8"
  }, {
    "type" : "bytes32",
    "name" : "r",
    "internalType" : "bytes32"
  }, {
    "type" : "bytes32",
    "name" : "s",
    "internalType" : "bytes32"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "payable",
  "outputs" : [ {
    "type" : "uint256[]",
    "name" : "amounts",
    "internalType" : "uint256[]"
  } ],
  "name" : "swapETHForExactTokens",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountOut",
    "internalType" : "uint256"
  }, {
    "type" : "address[]",
    "name" : "path",
    "internalType" : "address[]"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "payable",
  "outputs" : [ {
    "type" : "uint256[]",
    "name" : "amounts",
    "internalType" : "uint256[]"
  } ],
  "name" : "swapExactETHForTokens",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountOutMin",
    "internalType" : "uint256"
  }, {
    "type" : "address[]",
    "name" : "path",
    "internalType" : "address[]"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "payable",
  "outputs" : [ ],
  "name" : "swapExactETHForTokensSupportingFeeOnTransferTokens",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountOutMin",
    "internalType" : "uint256"
  }, {
    "type" : "address[]",
    "name" : "path",
    "internalType" : "address[]"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ {
    "type" : "uint256[]",
    "name" : "amounts",
    "internalType" : "uint256[]"
  } ],
  "name" : "swapExactTokensForETH",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountIn",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountOutMin",
    "internalType" : "uint256"
  }, {
    "type" : "address[]",
    "name" : "path",
    "internalType" : "address[]"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ ],
  "name" : "swapExactTokensForETHSupportingFeeOnTransferTokens",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountIn",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountOutMin",
    "internalType" : "uint256"
  }, {
    "type" : "address[]",
    "name" : "path",
    "internalType" : "address[]"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ {
    "type" : "uint256[]",
    "name" : "amounts",
    "internalType" : "uint256[]"
  } ],
  "name" : "swapExactTokensForTokens",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountIn",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountOutMin",
    "internalType" : "uint256"
  }, {
    "type" : "address[]",
    "name" : "path",
    "internalType" : "address[]"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ ],
  "name" : "swapExactTokensForTokensSupportingFeeOnTransferTokens",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountIn",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountOutMin",
    "internalType" : "uint256"
  }, {
    "type" : "address[]",
    "name" : "path",
    "internalType" : "address[]"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ {
    "type" : "uint256[]",
    "name" : "amounts",
    "internalType" : "uint256[]"
  } ],
  "name" : "swapTokensForExactETH",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountOut",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountInMax",
    "internalType" : "uint256"
  }, {
    "type" : "address[]",
    "name" : "path",
    "internalType" : "address[]"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "function",
  "stateMutability" : "nonpayable",
  "outputs" : [ {
    "type" : "uint256[]",
    "name" : "amounts",
    "internalType" : "uint256[]"
  } ],
  "name" : "swapTokensForExactTokens",
  "inputs" : [ {
    "type" : "uint256",
    "name" : "amountOut",
    "internalType" : "uint256"
  }, {
    "type" : "uint256",
    "name" : "amountInMax",
    "internalType" : "uint256"
  }, {
    "type" : "address[]",
    "name" : "path",
    "internalType" : "address[]"
  }, {
    "type" : "address",
    "name" : "to",
    "internalType" : "address"
  }, {
    "type" : "uint256",
    "name" : "deadline",
    "internalType" : "uint256"
  } ]
}, {
  "type" : "receive",
  "stateMutability" : "payable"
} ]
Do you wish to import this ABi? [y/n] y
[info] A default ABI is now known for the contract at address 0x1C232F01118CB8B424793ae03F870aa7D0ac7f77
Enter an optional alias for the address '0x1C232F01118CB8B424793ae03F870aa7D0ac7f77', now associated with the newly imported default ABI (or [return] for none): 
[info] No alias set for the address '0x1C232F01118CB8B424793ae03F870aa7D0ac7f77', now associated with the newly imported default ABI.
[info] Refreshing caches.
[success] Total time: 17 s, completed Mar 19, 2021, 12:10:36 AM