Is it possible to export Xpub Key from Ledger Nano S Ethereum Wallet - ethereum

I need to give payment ETH address to my customers for deposit ETH their accounts. I want to use a HD ETH wallet for this and I am using Ledger Nano S now. But Ledger showing me only 1 receive address so I need ETH wallet's XPub for generate many address from it for distribute to users.
If Ledger support HD, How can I export XPub? If ledger does not support, Which wallet can usable for this purpose.
Any suggestions.

You can't export the xpub directly from a ledger nano s with the default bitcoin or ethereum apps.
But you can construct an xpub using the data you can extract from the ledger.
What you need is the public key and chaincode for the bip32 path you're interested in and the public key of the parent of that path.
In the ethereum app you would use getaddress (currently there is a restriction to m/44/60', m/44'/61', and m/44'/1' and below for this app (I have an issue here to hopefully remove that restriction). In the bitcoin app you would use getwalletpublickey. There is no bip32 path restrictions in the bitcoin app.
Once you have the two public keys and the chain code, you can construct the xpub. Here is a chunk of python that can accomplish this. It uses the un-maintained pybitcointools, so user-beware.
#!/usr/bin/env python
import sys
import binascii
from bitcoin import bin_hash160
from bitcoin import bip32_serialize
from bitcoin import compress
def main(parent_pubkey, pubkey, chaincode, depth, index, network):
if (network.lower() == "main"):
network_bytes = b'\x04\x88\xb2\x1e'
elif (network.lower() == "test"):
network_bytes = b'\x04\x35\x87\xcf'
else:
sys.exit("network must be either main or test")
compressed_pubkey_bytes = binascii.unhexlify(compress(pubkey))
fingerprint_bytes = bin_hash160(binascii.unhexlify(compress(parent_pubkey)))[:4]
chaincode_bytes = binascii.unhexlify(chaincode)
deserialized = (network_bytes, int(depth), fingerprint_bytes, int(index), chaincode_bytes, compressed_pubkey_bytes)
xpub = bip32_serialize(deserialized)
print(xpub)
if __name__ == '__main__':
if (len(sys.argv) < 7):
sys.exit("USAGE: generate_xpub PARENT_PUBLICKEY PUBLICKEY CHAINCODE DEPTH INDEX (MAIN|TEST)")
main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])

Related

Get list of recent added/deployed smart contracts

Is there a way to retrieve the most recent added/deployed smart contracts to the ethereum chain?
Thanks a lot for any advice.
Regards,
JR
Newly deployed contract addresses are not directly available through the node RPC API (and its wrappers such as ethersjs and web3js), but you can build a script that
Subscribes to newly published blocks
Loops through transaction receipts on the block
And searches for contractAddress property of the transaction receipt
The contractAddress property returns null if the transaction does not deploy a contract (most transactions) or an address if the transaction deploys a contract.
The above mentioned approach only retrieves contracts that were deployed directly - by sending a transaction with empty to field and data field containing the contract bytecode.
It does not retrieve contracts that were deployed using an internal transaction. For example it would not catch the following Hello contract deployment (that is deployed by executing the deployHello() function).
pragma solidity ^0.8;
contract Hello {}
contract HelloFactory {
event Deployed(address);
function deployHello() external {
// deploys a new instance of the `Hello` contract to a new address
address deployedTo = address(
new Hello()
);
emit Deployed(deployedTo);
}
}
If you want to retrieve deployments of these contracts as well, then you'd need to debug each newly produced block and search for the create and create2 opcodes (each of them deploys a new contract, they take different input arguments).
So overall, it's not a simple task but it's doable.
It's generally discouraged to recommend any specific 3rd party APIs and tools here at StackOverflow. But I'm guessing that there are already some existing services that do all of this on their backend, and are able to return the aggregated list of newly deployed contracts as a result.
Thanks to the help of Petr Hejda I created the following Python code:
import sys
import time
from web3 import Web3
def connect():
# infura API key
API_KEY = "INFURA_API_KEY"
# change endpoint to mainnet or ropsten or any other of your account
url = f"https://mainnet.infura.io/v3/{API_KEY}"
w3 = Web3(Web3.HTTPProvider(url))
# res = w3.isConnected()
# print(res)
return w3
def get_latest_block(connection):
return connection.eth.get_block('latest')
def get_latest_block_id(block_information):
return block_information['number']
def search_new_contracts(connection, block_information):
block_transactions = block_information['transactions']
# print(block_transactions)
for transaction in block_transactions:
transaction_data = connection.eth.getTransaction(transaction)
if transaction_data['to'] == "":
print(f"Contract creation transaction: {transaction_data}")
print("Block searching done")
if __name__ == "__main__":
current_block_number = sys.maxsize
connection = connect()
while True:
latest_block = get_latest_block(connection)
latest_block_id = get_latest_block_id(latest_block)
if current_block_number is not latest_block_id:
print(f'New block detected: {latest_block_id}')
search_new_contracts(connection, latest_block)
current_block_number = latest_block_id
Problem is that it is slow so I have to see if I can speed things up.

Can ETH miners check all the data which is stored in Ethereum?

My doubt is from the below code:
contract RandomNumber{
uint number;
function get_random() public{
bytes32 ramdonNumber = keccak256(abi.encodePacked(block.timestamp,blockhash(block.number-1)));
number = uint(ramdonNumber);
}
}
We assign a random number to the variable number but if I don't set number public or create another public function to retrieve the value then nobody would know the exactly value through Etherscan. But what about the miners? Can they retrieve these unrevealed data in some ways?
I have tried:
Google, Ethereum whitepaper, Solidity documentation
Assuming that the contract is deployed on a public network (e.g. Ethereum), then the value is always readable.
Not directly through the autogenerated getter function (that's available only for public properties), which means it's not available onchain.
But anyone (including miners) can create an offchain app (for example in JavaScript) that queries the specific storage slot where the value is stored - in this case it's in slot number 0. And it returns the "secret" value.
JS code using ethers library, a wrapper to RPC API of Ethereum nodes:
const number = await provider.getStorageAt(CONTRACT_ADDRESS, SLOT_NUMBER);
Docs: https://docs.ethers.org/v5/api/providers/provider/#Provider-getStorageAt
And the actual RPC API method: https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getstorageat

How to generate arbitrary wallet seeded with eth in hardhat tests using ethers.js?

I'm currently trying to run a test in hardhat/waffle that requires hundreds of unique wallets to call a contract, using new ethers.Wallet.createRandom(). However, none of these wallets are supplied with eth, so I can't call/send transactions with them.
What would be the simplest/most effective way to supply an arbitrary amount of randomly generated wallets with eth? Thanks!
I think you'll probably want to use the hardhat network method hardhat_setBalance, the docs use an example like this:
await network.provider.send("hardhat_setBalance", [
"<ACCOUNT ADDRESS>",
"0x1000", # 4096 wei
]);
I'm not developing in javascript though, but I've been doing something similar in python using web3.py and eth-account with code like this:
from web3 import Web3
from eth_account import Account
chain = Web3(HTTPProvider("http://127.0.0.1:8545"))
acct = Account.create('<RANDOM VALUE>')
address = Web3.toChecksumAddress(acct.address)
print(chain.eth.get_balance(address)) # 0 wei
# add a balance of eth tokens to the address
chain.provider.make_request("hardhat_setBalance", [address, "0x1000"])
print(chain.eth.get_balance(address)) # 4096 wei
Hardhat allows to seed a custom amount of prefunded addresses using the accounts.count config option of the built-in hardhat network.
Example:
module.exports = {
networks: {
hardhat: {
accounts: {
count: 1000
}
}
}
}
Docs: https://hardhat.org/hardhat-network/reference/#config
The new ethers.Wallet.createRandom() function only creates an account from a random private key in the context of the JS application, but it doesn't communicate with the provider (Hardhat in your case).
saw this answer, and i think it solves the problem:
https://github.com/ethers-io/ethers.js/issues/686
const wallet = ethers.Wallet.createRandom().connect(provider);

How to inject Binance Wallet into Web3 instead of Metamask?

I started using Binance Chain Wallet in my dapp, so I can now use:
import { BscConnector } from '#binance-chain/bsc-connector'
export const bsc = new BscConnector({
supportedChainIds: [56, 97] // later on 1 ethereum mainnet and 3 ethereum ropsten will be supported
})
// invoke method on bsc e.g.
await bsc.activate();
await bsc.getAccount();
await bsc.getChainId();
but in API docs it says to do some chain operations I need to iject :
The biggest difference between Binance Chain Wallet and MetaMask is we inject BinanceChain rather than ethereum (or web3) to the web page. So user could keep two extensions at the same time.
BinanceChain.request({method: "eth_sign", params: ["address", "message"])
with metamsk I use
ethereum.request(...)
can you explain to me how to do this?
BinanceChain obj is not declared :)
So I figured out that these steps are necessarily :
// create instance of bsc wallet
const bsc = new BscConnector({
supportedChainIds: [56, 97, 1] // later on 1 ethereum mainnet and 3 ethereum ropsten will be supported
})
// get provider out of this instance:
const bsc_provider = await bsc.getProvider()
provider = new ethers.providers.Web3Provider(bsc_provider)
// from here u can use all binance wallet functions:
provider.provider.switchNetwork('eth-mainnet')
see docs:
binance wallet docs

Can I import NFT's metadata into a smart contract?

When we want to mint an NFT with its own metadata, the asset file and JSON file should be uploaded to IPFS before the minting.
And we mint a new NFT by sending transactions to the smart contract and within the transaction, the token URI(hashed URI from IPFS) would be set as JSON metadata URI of the token.
Now I am wondering whether there is a way to import the attributes from JSON on IPFS into a smart contract and use the data like const variables in the contract.
You can do it but it is going to cost you alot. You need to create a mapping in smart contract.
mapping(string ->Metadata) private tokenURIToMetadata
Since it is mapped from string, it cannot be public. so create a function
function getMetadata(string tokenUri) public returns(Metadata){
return tokenURIToMetadata[tokenUri]
}
also create Metadata struct:
struct Metadata{
string name;
string description;
string image;
}
And then you have to add new medata to the mapping:
function addMetada(string memory tokenUri,?????????){}
Since we cannot pass json object as an argument to the addMetada, now you have to create a separate mapping for each property of the metadata object. So the cost will be crazy amount.
Instead, you could write the metadata to the filesystem or database but this would not be a good option.