pub fn cpu(config: Config) -> Result<(), Box<dyn Error>> {
    // (create if necessary) and open a file where found salts will be written
    let file = OpenOptions::new()
                 .append(true)
                 .create(true)
                 .open("efficient_addresses.txt")
                 .expect(
                   "Could not create or open `efficient_addresses.txt` file."
                 );

    // create object for computing rewards (relative rarity) for a given address
    let rewards = reward::Reward::new();

    // set "footer" of hash message using initialization code hash from config
    let footer: [u8; 32] = config.init_code_hash;

    // create a random number generator
    let mut rng = thread_rng();

    // begin searching for addresses
    loop {
        // create a random 6-byte salt using the random number generator
        let salt_random_segment = rng.gen_iter::<u8>()
                                    .take(6)
                                    .collect::<Vec<u8>>();

        // header: 0xff ++ factory ++ caller ++ salt_random_segment (47 bytes)
        let mut header_vec: Vec<u8> = vec![CONTROL_CHARACTER];
        header_vec.extend(config.factory_address.iter());
        header_vec.extend(config.calling_address.iter());
        header_vec.extend(salt_random_segment);

        // convert the header vector to a fixed-length array
        let header: [u8; 47] = to_fixed_47(&header_vec);

        // create new hash object
        let mut hash_header = Keccak::new_keccak256();

        // update hash with header
        hash_header.update(&header);

        // iterate over a 6-byte nonce and compute each address
        (0..MAX_INCREMENTER)
          .into_par_iter() // parallelization
          .map(|x| u64_to_fixed_6(&x)) // convert int nonces to fixed arrays
          .for_each(|salt_incremented_segment| {
            // clone the partially-hashed object
            let mut hash = hash_header.clone();

            // update with body and footer (total: 38 bytes)
            hash.update(&salt_incremented_segment);
            hash.update(&footer);

            // hash the payload and get the result
            let mut res: [u8; 32] = [0; 32];
            hash.finalize(&mut res);

            // get the total zero bytes associated with the address
            let total = res
                          .iter()
                          .dropping(12)
                          .filter(|&n| *n == ZERO_BYTE)
                          .count();

            // only proceed if there are at least three zero bytes
            if total > 2 {
                // get the leading zero bytes associated with the address
                let mut leading = 0;

                // iterate through each byte of address and count zero bytes
                for (i, b) in res.iter().dropping(12).enumerate() {
                    if b != &ZERO_BYTE {
                        leading = i; // set leading on finding non-zero byte
                        break;       // stop searching upon locating
                    }
                }

                // look up the reward amount
                let key = leading * 20 + total;
                let reward_amount = rewards.get(&key);

                // proceed if an efficient address has been found
                if reward_amount != ZERO_REWARD {
                    // truncate first 12 bytes from the hash to derive address
                    let mut address_bytes: [u8; 20] = Default::default();
                    address_bytes.copy_from_slice(&res[12..]);

                    // get the address that results from the hash
                    let address_hex_string = hex::encode(&address_bytes);
                    let address = format!("{}", &address_hex_string);

                    // get the full salt used to create the address
                    let header_hex_string = hex::encode(&header_vec);
                    let body_hex_string = hex::encode(salt_incremented_segment
                                                        .to_vec());
                    let full_salt = format!(
                      "0x{}{}",
                      &header_hex_string[42..],
                      &body_hex_string
                    );

                    // encode address and set up a variable for the checksum
                    let address_encoded = address.as_bytes();
                    let mut checksum_address = "0x".to_string();

                    // create new hash object for computing the checksum
                    let mut checksum_hash = Keccak::new_keccak256();

                    // update with utf8-encoded address (total: 20 bytes)
                    checksum_hash.update(&address_encoded);

                    // hash the payload and get the result
                    let mut checksum_res: [u8; 32] = [0; 32];
                    checksum_hash.finalize(&mut checksum_res);
                    let address_hash = hex::encode(checksum_res);

                    // compute the address checksum using the above hash
                    for nibble in 0..address.len() {
                        let hash_character = i64::from_str_radix(
                          &address_hash
                            .chars()
                            .nth(nibble)
                            .unwrap()
                            .to_string(),
                          16
                        ).unwrap();
                        let character = address.chars().nth(nibble).unwrap();
                        if hash_character > 7 {
                            checksum_address = format!(
                              "{}{}",
                              checksum_address,
                              character.to_uppercase().to_string()
                            );
                        } else {
                            checksum_address = format!(
                              "{}{}",
                              checksum_address,
                              character.to_string()
                            );
                        }
                    }

                    // display the salt and the address.
                    let output = format!(
                      "{} => {} => {}",
                      full_salt,
                      checksum_address,
                      reward_amount
                    );
                    println!("{}", &output);

                    // create a lock on the file before writing
                    file.lock_exclusive().expect("Couldn't lock file.");

                    // write the result to file
                    writeln!(&file, "{}", &output).expect(
                      "Couldn't write to `efficient_addresses.txt` file."
                    );

                    // release the file lock
                    file.unlock().expect("Couldn't unlock file.")
                }
            }
        });
    }
}
/// Given a Config object with a factory address, a caller address, and a
/// keccak-256 hash of the contract initialization code, search for salts that
/// will enable the factory contract to deploy a contract to a gas-efficient
/// address via CREATE2.
///
/// The 32-byte salt is constructed as follows:
///   - the 20-byte calling address (to prevent frontrunning)
///   - a random 6-byte segment (to prevent collisions with other runs)
///   - a 6-byte nonce segment (incrementally stepped through during the run)
///
/// When a salt that will result in the creation of a gas-efficient contract
/// address is found, it will be appended to `efficient_addresses.txt` along
/// with the resultant address and the "value" (i.e. approximate rarity) of the
/// resultant address.
Given a Config object with a factory address, a caller address, and a
keccak-256 hash of the contract initialization code, search for salts that
will enable the factory contract to deploy a contract to a gas-efficient
address via CREATE2.

The 32-byte salt is constructed as follows:
the 20-byte calling address (to prevent frontrunning)
a random 6-byte segment (to prevent collisions with other runs)
a 6-byte nonce segment (incrementally stepped through during the run)

When a salt that will result in the creation of a gas-efficient contract
address is found, it will be appended to `efficient_addresses.txt` along
with the resultant address and the "value"  of the
resultant address.
Given a Config object with a factory address a caller address and a keccak - 256 hash of the contract initialization code search for salts that will enable the factory contract to deploy a contract to a gas - efficient address via CREATE2 . The 32 - byte salt is constructed as follows : the 20 - byte calling address ( to prevent frontrunning ) a random 6 - byte segment ( to prevent collisions with other runs ) a 6 - byte nonce segment ( incrementally stepped through during the run ) When a salt that will result in the creation of a gas - efficient contract address is found it will be appended to ` efficient_addresses . txt ` along with the resultant address and the " value " of the resultant address .
pub fn cpu(config: Config) -> Result<(), Box<dyn Error>> {
    // (create if necessary) and open a file where found salts will be written
    let file = OpenOptions::new()
                 .append(true)
                 .create(true)
                 .open("efficient_addresses.txt")
                 .expect(
                   "Could not create or open `efficient_addresses.txt` file."
                 );
    // create object for computing rewards (relative rarity) for a given address
    let rewards = reward::Reward::new();
    // set "footer" of hash message using initialization code hash from config
    let footer: [u8; 32] = config.init_code_hash;
    // create a random number generator
    let mut rng = thread_rng();
    // begin searching for addresses
    loop {
        // create a random 6-byte salt using the random number generator
        let salt_random_segment = rng.gen_iter::<u8>()
                                    .take(6)
                                    .collect::<Vec<u8>>();
        // header: 0xff ++ factory ++ caller ++ salt_random_segment (47 bytes)
        let mut header_vec: Vec<u8> = vec![CONTROL_CHARACTER];
        header_vec.extend(config.factory_address.iter());
        header_vec.extend(config.calling_address.iter());
        header_vec.extend(salt_random_segment);
        // convert the header vector to a fixed-length array
        let header: [u8; 47] = to_fixed_47(&header_vec);
        // create new hash object
        let mut hash_header = Keccak::new_keccak256();
        // update hash with header
        hash_header.update(&header);
        // iterate over a 6-byte nonce and compute each address
        (0..MAX_INCREMENTER)
          .into_par_iter() // parallelization
          .map(|x| u64_to_fixed_6(&x)) // convert int nonces to fixed arrays
          .for_each(|salt_incremented_segment| {
            // clone the partially-hashed object
            let mut hash = hash_header.clone();
            // update with body and footer (total: 38 bytes)
            hash.update(&salt_incremented_segment);
            hash.update(&footer);
            // hash the payload and get the result
            let mut res: [u8; 32] = [0; 32];
            hash.finalize(&mut res);
            // get the total zero bytes associated with the address
            let total = res
                          .iter()
                          .dropping(12)
                          .filter(|&n| *n == ZERO_BYTE)
                          .count();
            // only proceed if there are at least three zero bytes
            if total > 2 {
                // get the leading zero bytes associated with the address
                let mut leading = 0;
                // iterate through each byte of address and count zero bytes
                for (i, b) in res.iter().dropping(12).enumerate() {
                    if b != &ZERO_BYTE {
                        leading = i; // set leading on finding non-zero byte
                        break;       // stop searching upon locating
                    }
                }
                // look up the reward amount
                let key = leading * 20 + total;
                let reward_amount = rewards.get(&key);
                // proceed if an efficient address has been found
                if reward_amount != ZERO_REWARD {
                    // truncate first 12 bytes from the hash to derive address
                    let mut address_bytes: [u8; 20] = Default::default();
                    address_bytes.copy_from_slice(&res[12..]);
                    // get the address that results from the hash
                    let address_hex_string = hex::encode(&address_bytes);
                    let address = format!("{}", &address_hex_string);
                    // get the full salt used to create the address
                    let header_hex_string = hex::encode(&header_vec);
                    let body_hex_string = hex::encode(salt_incremented_segment
                                                        .to_vec());
                    let full_salt = format!(
                      "0x{}{}",
                      &header_hex_string[42..],
                      &body_hex_string
                    );
                    // encode address and set up a variable for the checksum
                    let address_encoded = address.as_bytes();
                    let mut checksum_address = "0x".to_string();
                    // create new hash object for computing the checksum
                    let mut checksum_hash = Keccak::new_keccak256();
                    // update with utf8-encoded address (total: 20 bytes)
                    checksum_hash.update(&address_encoded);
                    // hash the payload and get the result
                    let mut checksum_res: [u8; 32] = [0; 32];
                    checksum_hash.finalize(&mut checksum_res);
                    let address_hash = hex::encode(checksum_res);
                    // compute the address checksum using the above hash
                    for nibble in 0..address.len() {
                        let hash_character = i64::from_str_radix(
                          &address_hash
                            .chars()
                            .nth(nibble)
                            .unwrap()
                            .to_string(),
                          16
                        ).unwrap();
                        let character = address.chars().nth(nibble).unwrap();
                        if hash_character > 7 {
                            checksum_address = format!(
                              "{}{}",
                              checksum_address,
                              character.to_uppercase().to_string()
                            );
                        } else {
                            checksum_address = format!(
                              "{}{}",
                              checksum_address,
                              character.to_string()
                            );
                        }
                    }
                    // display the salt and the address.
                    let output = format!(
                      "{} => {} => {}",
                      full_salt,
                      checksum_address,
                      reward_amount
                    );
                    println!("{}", &output);
                    // create a lock on the file before writing
                    file.lock_exclusive().expect("Couldn't lock file.");
                    // write the result to file
                    writeln!(&file, "{}", &output).expect(
                      "Couldn't write to `efficient_addresses.txt` file."
                    );
                    // release the file lock
                    file.unlock().expect("Couldn't unlock file.")
                }
            }
        });
    }
}
pub fn cpu ( config : Config ) -> Result < ( ) , Box < dyn Error > > { // (create if necessary) and open a file where found salts will be written let file = OpenOptions :: new ( ) . append ( true ) . create ( true ) . open ( " " ) . expect ( " " ) ; // create object for computing rewards (relative rarity) for a given address let rewards = reward :: Reward :: new ( ) ; // set "footer" of hash message using initialization code hash from config let footer : [ u8 ; 32 ] = config . init_code_hash ; // create a random number generator let mut rng = thread_rng ( ) ; // begin searching for addresses loop { // create a random 6-byte salt using the random number generator let salt_random_segment = rng . gen_iter :: < u8 > ( ) . take ( 6 ) . collect :: < Vec < u8 > > ( ) ; // header: 0xff ++ factory ++ caller ++ salt_random_segment (47 bytes) let mut header_vec : Vec < u8 > = vec ! [ CONTROL_CHARACTER ] ; header_vec . extend ( config . factory_address . iter ( ) ) ; header_vec . extend ( config . calling_address . iter ( ) ) ; header_vec . extend ( salt_random_segment ) ; // convert the header vector to a fixed-length array let header : [ u8 ; 47 ] = to_fixed_47 ( & header_vec ) ; // create new hash object let mut hash_header = Keccak :: new_keccak256 ( ) ; // update hash with header hash_header . update ( & header ) ; // iterate over a 6-byte nonce and compute each address ( 0 .. MAX_INCREMENTER ) . into_par_iter ( ) // parallelization . map ( | x | u64_to_fixed_6 ( & x ) ) // convert int nonces to fixed arrays . for_each ( | salt_incremented_segment | { // clone the partially-hashed object let mut hash = hash_header . clone ( ) ; // update with body and footer (total: 38 bytes) hash . update ( & salt_incremented_segment ) ; hash . update ( & footer ) ; // hash the payload and get the result let mut res : [ u8 ; 32 ] = [ 0 ; 32 ] ; hash . finalize ( & mut res ) ; // get the total zero bytes associated with the address let total = res . iter ( ) . dropping ( 12 ) . filter ( | & n | * n == ZERO_BYTE ) . count ( ) ; // only proceed if there are at least three zero bytes if total > 2 { // get the leading zero bytes associated with the address let mut leading = 0 ; // iterate through each byte of address and count zero bytes for ( i , b ) in res . iter ( ) . dropping ( 12 ) . enumerate ( ) { if b != & ZERO_BYTE { leading = i ; // set leading on finding non-zero byte break ; // stop searching upon locating } } // look up the reward amount let key = leading * 20 + total ; let reward_amount = rewards . get ( & key ) ; // proceed if an efficient address has been found if reward_amount != ZERO_REWARD { // truncate first 12 bytes from the hash to derive address let mut address_bytes : [ u8 ; 20 ] = Default :: default ( ) ; address_bytes . copy_from_slice ( & res [ 12 .. ] ) ; // get the address that results from the hash let address_hex_string = hex :: encode ( & address_bytes ) ; let address = format ! ( " " address_hex_string ) ; // get the full salt used to create the address let header_hex_string = hex :: encode ( & header_vec ) ; let body_hex_string = hex :: encode ( salt_incremented_segment . to_vec ( ) ) ; let full_salt = format ! ( " " header_hex_string [ 42 ] body_hex_string ) ; // encode address and set up a variable for the checksum let address_encoded = address . as_bytes ( ) ; let mut checksum_address = " " . to_string ( ) ; // create new hash object for computing the checksum let mut checksum_hash = Keccak :: new_keccak256 ( ) ; // update with utf8-encoded address (total: 20 bytes) checksum_hash . update ( & address_encoded ) ; // hash the payload and get the result let mut checksum_res : [ u8 ; 32 ] = [ 0 ; 32 ] ; checksum_hash . finalize ( & mut checksum_res ) ; let address_hash = hex :: encode ( checksum_res ) ; // compute the address checksum using the above hash for nibble in 0 .. address . len ( ) { let hash_character = i64 :: from_str_radix ( & address_hash . chars ( ) . nth ( nibble ) . unwrap ( ) . to_string ( ) , 16 ) . unwrap ( ) ; let character = address . chars ( ) . nth ( nibble ) . unwrap ( ) ; if hash_character > 7 { checksum_address = format ! ( " " checksum_address character to_uppercase ( ) to_string ( ) ) ; } else { checksum_address = format ! ( " " checksum_address character to_string ( ) ) ; } } // display the salt and the address. let output = format ! ( " " full_salt checksum_address reward_amount ) ; println ! ( " " output ) ; // create a lock on the file before writing file . lock_exclusive ( ) . expect ( " " ) ; // write the result to file writeln ! ( file " " output ) . expect ( " " ) ; // release the file lock file . unlock ( ) . expect ( " " ) } } } ) ; } }
Given a Config object with a factory address, a caller address, and a
keccak-256 hash of the contract initialization code, search for salts that
will enable the factory contract to deploy a contract to a gas-efficient
address via CREATE2.
Given a Config object with a factory address a caller address and a keccak - 256 hash of the contract initialization code search for salts that will enable the factory contract to deploy a contract to a gas - efficient address via CREATE2 .
config
Config
config
Config