Why does this code throw a (ambiguous) internal compiler error? - ethereum

This function produces the following error (compiled by hardhat)
Solidity 0.8.7
contract TestContract {
function slice(string calldata source, uint from, uint to) public pure returns(string memory) {
bytes calldata b = (bytes(source));
uint len = b.length;
require(to < len && to>=from, "indexes out of bounds");
string memory retval = string(b[from:to]);
return retval;
}
}
The error I get is Compiling 1 file with 0.8.7 InternalCompilerError: Internal compiler error (/Users/distiller/project/libsolidity/codegen/CompilerUtils.cpp:1116) Error HH600: Compilation failed

I'm not sure about how you convert bytes to string, but the error might come from string(b[from:to]);. You can reference the byteToString function provided here https://ethereum.stackexchange.com/questions/29295/how-to-convert-a-bytes-to-string-in-solidity.

Related

Solidity how to validate calldata decodes to a paticular struct

I have an interface in solidity which looks like so, I would like my call to revert if the calldata passed isn't of a specific type
// Resolver interface
interface IResolver {
// Pass payment info as calldata only the manager should have the right to update it
function resolve(uint256 amount, ResolverOptions calldata resolverOptions) external returns (uint256);
// Reverts if the calldata passes is not a proper struct
function validateAdditionalCalldata(bytes calldata additionalCalldata) external view;
}
I've created a class to implement this here:
struct fooResolverOptions {
address[] fooAddresses;
uint256[] fooAmounts;
}
contract FooResolver is IResolver {
// Validate the additional calldata passed to the resolver contract
function validateAdditionalCalldata(bytes calldata additionalCalldata) view external {
// Convert the additional calldata to bytes memory
bytes memory additionalCalldataMemory = additionalCalldata;
// Decode the additional calldata as a FooResolverOptions struct
FooResolverOptions memory fooOptions;
bool success = abi.decode(additionalCalldataMemory, fooOptions);
// Check if the decode was successful
require(success, "Invalid additional calldata");
}
}
None of the Way's I've tried to decode work:
bool success = abi.decode(additionalCalldataMemory, fooOptions);
this way claims there is no return value from decode.
FooResolverOptions memory fooOptions;
abi.decode(additionalCalldata, fooOptions);
This way claims it wants a tuple of types. How do I decode a struct data, and validate it succeeded?
Solidity currently (v0.8) doesn't support dynamic arguments in abi.decode(), so you'll need to write logic that validates against predefined set of types.
bytes calldata additionalCalldata in your example is an array of bytes, so abi.decode(additionalCalldataMemory, <types>); tries to decode the binary to whatever <types> you pass. If the input fits the type length, it will simply decode the value to the type.
Example where the value fits into both bool and address types, so both operations succeed:
function validateAdditionalCalldata() pure external returns (bool, address) {
bytes memory additionalCalldataMemory = hex"0000000000000000000000000000000000000000000000000000000000000001";
bool decoded1 = abi.decode(additionalCalldataMemory, (bool));
address decoded2 = abi.decode(additionalCalldataMemory, (address));
return (decoded1, decoded2);
}
When the value doesn't fit the type, it throws an exception. Uncaught exception effectively reverts the transaction or the call. However, you can use try / catch to catch the exception.
pragma solidity ^0.8;
contract FooResolver {
function validateAdditionalCalldata() external view returns (bool, address) {
// does not fit `bool` but still fits `address`
bytes memory additionalCalldataMemory = hex"0000000000000000000000000000000000000000000000000000000000000002";
bool decoded1;
try this.decodeToBool(additionalCalldataMemory) returns (bool decodedValue) {
decoded1 = decodedValue;
} catch {
decoded1 = false;
}
address decoded2 = abi.decode(additionalCalldataMemory, (address));
return (decoded1, decoded2);
}
// workaround - try/catch can be currently (v0.8) used on external function calls - but not on native function calls
function decodeToBool(bytes memory data) external pure returns (bool) {
return abi.decode(data, (bool));
}
}

Invalid implicit conversion from address payable to bytes memory requested. This function requires a single bytes argument

function setBasicDetails(string memory _registrationNo,
string memory _farmerName,
string memory _farmAddress,
string memory _exporterName,
string memory _importerName
) public onlyAuthCaller returns(address) {
uint tmpData = uint(keccak256(msg.sender));
address batchNo = address(tmpData);
basicDetailsData.registrationNo = _registrationNo;
basicDetailsData.farmerName = _farmerName;
basicDetailsData.farmAddress = _farmAddress;
basicDetailsData.exporterName = _exporterName;
basicDetailsData.importerName = _importerName;
batchBasicDetails[batchNo] = basicDetailsData;
nextAction[batchNo] = 'FARM_INSPECTION';
return batchNo;
}
this is my solidity function code and i have error here's code
uint tmpData = uint(keccak256(msg.sender));
address batchNo = address(tmpData);
error msg:Invalid type for argument in function call. Invalid implicit conversion from address payable to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.
If that is the only error in your code ()
keccak256(msg.sender)
keccak256 will return 32 bytes hash. but the address is 20 bytes. so instead of uint you should be using uint160
uint tmpData = uint160(keccak256(msg.sender))

Gas estimation error during calling the funtion

// I am getting gas estimation error while calling the function "drawNumbers". Can anyone please explain why I'm getting this error
pragma solidity ^0.8.0;
contract ABC{
uint max = 3;
uint[] numbers;
mapping(uint => bool) isNFTWon;
function drawNumbers() public returns (uint256[] memory) {
for(uint i=0; i<max; i++){
uint Ids = uint (keccak256(abi.encodePacked(block.timestamp, block.difficulty, msg.sender))) % 1000;
if(isNFTWon[Ids] == true){
i -= 1;
continue;
}
isNFTWon[Ids] = true;
numbers.push(Ids);
}
return numbers;
}
}
// I'm getting this error-----
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Internal JSON-RPC error. { "code": -32000, "message": "gas required exceeds allowance (20000000)" }
This error shows that your transaction is going to be reverted. There is probably some requirement state failure or call failure.
The problem is seems like on line
i -= 1;
i is uint variable and when you decrementing the value of i, can underflow but with solidity version 0.8+ there is overflow/underflow check by default. If you want to try to better understand the problem is you can simply decrease your solidity version under 0.8 or bracket these lines like
unchecked {
i -= 1;
}
If value of i will rise to uint max. then we can decide that the problem caused by that.

Error: invalid argument 0: json: cannot unmarshal hex string without 0x prefix into Go struct field TransactionArgs.data of type hexutil.Bytes

Make solidity file and compile with this
solcjs --bin --abi -o bin HelloWorld.sol
HelloWorld.sol
pragma solidity ^0.4.15;
contract HelloWorld{
address owner;
string greeting = "Hello World";
function HelloWorld() public {
owner = msg.sender;
}
function greet () constant public returns (string){
return greeting;
}
function kill () public {
require(owner == msg.sender);
selfdestruct(owner);
}
}
HelloWorld_sol_HelloWorld.bin file is made.
then start geth console --rinkeby
set bytecode in console like this
>bytecode =
"60606040526040805190810160405280600b81526020017f48656c6c6f20576f726c640000000000000000000000000000000000000000008152506001908051906020019061004f9291906100a0565b50341561005b57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610145565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100e157805160ff191683800117855561010f565b8280016001018555821561010f579182015b8281111561010e5782518255916020019190600101906100f3565b5b50905061011c9190610120565b5090565b61014291905b8082111561013e576000816000905550600101610126565b5090565b90565b610271806101546000396000f30060606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b514610051578063cfae321714610066575b600080fd5b341561005c57600080fd5b6100646100f4565b005b341561007157600080fd5b610079610189565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100b957808201518184015260208101905061009e565b50505050905090810190601f1680156100e65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3373ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561014f57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b610191610231565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102275780601f106101fc57610100808354040283529160200191610227565b820191906000526020600020905b81548152906001019060200180831161020a57829003601f168201915b5050505050905090565b6020604051908101604052806000815250905600a165627a7a7230582066f5cd1b6d6dd19f1efb8ff4a038afbea3cb598f0ac1f77a0c7335c2c230705e0029"
Now try to send this
>tx = eth.sendTransaction({from: eth.accounts[0],data:bytecode,gas:500e3})
comes the error below.
Error: invalid argument 0: json: cannot unmarshal hex string without 0x prefix into Go struct field TransactionArgs.data of type hexutil.Bytes
Why it happens??

I get a declaration error in solidity when I create a variable with "var"

I'm trying to create a variable "project" to store data from a mapping but I get "Decalration error, undefined identifier" on project = projects[addr]
function getProjectInfo(address addr) public view returns (string memory name, string memory url, uint funds){
var project = projects[addr];
}```
Use explicit variable type definition:
pragma solidity ^0.5.8;
contract Test
{
struct Project
{
bytes32 name ;
}
mapping (address => Project) projects ;
constructor () public {
}
function getProjectInfo(address addr) public view returns (string memory name, string memory url, uint funds)
{
Project memory project = projects[addr];
// ...
}
}