I read a very good article on "Programming Smart Contracts on Ethereum" in the Jan/Feb 2023 issue of Code magazine.
The author uses Solidity to create a contract to read/write a string containing sensitive data. He first base64 encodes a JSON string and then passes it to the contract which is converted to a hash (to reduce gas fees) and written to the blockchain.
However, the only method in the contract is to verify that the proof exists by looking for the hash. This means you have to know ahead of time the data that was stored, encode it, and then search for the proof based on that hash.
But if you don't know what data you need, you can't create a hash. e.g. Retrieving all customer payment transactions
The approach I see to this is storing the block number to a local database. Then fetch the data using the block number.
example db table:
tblTransactions
-customerID(int)
-blockNumber(string)
My questions are:
Can you retrieve data using a block number?
Is this the best approach?
End goal is to find all used addresses of a xpub programmatically, in batches, by querying a local node.
This PHP tool ( https://github.com/dan-da/hd-wallet-addrs ) extracts regular bitcoin addresses from an HD bitcoin wallet . I have to query a local bitcoin node to find out whether the extracted addresses have been used or not.This can easily be found out by querying the node one address at a time ( https://bitco.in/en/developer-reference#getreceivedbyaddress ). It works, but is too slow.
How can the same be done in batches ? i.e is there a Core function call or something to check info about a group of addresses ?
or any other way this can be accomplished ? I am relatively new to bitcoin and don't fully understand its inner workings.
P.S: can't use an external API like blockchain.info
With importAddress and rescan (3 paramter) set to true, you can add the addresses that you want watch.
Than with listTransactions you can list the last transactions that affect the imported address.
I'm new in bitcoin.
I need to create something like a temporary bitcoin wallet for the currency exchange app. The wallet should be alive just one exchange transaction or 2 days(if the transaction wouldn't confirmed) and then should be removed.
But as I understand right from bitcoin docs - I cannot remove a wallet, because it is sort a "public key".
Any suggestions?
A 'wallet' doesn't actually really exist. All it is, is a collection of private keys (or just one private key that can be used to derive other keys from, like HD wallets do). These private keys allow you to spend the unspent output (UTXO), thus make a transaction.
These private keys are used to generate public keys, and from those the addresses are generated. You can't remove these addresses because they just exist. In fact, every address already exists, you just need the private key to access them.
Removing things from the blockchain wouldn't make sense anyway, the blockchain is literally a chain of blocks, each block being a container filled with transactions. If you would remove a transaction from a block, all the following blocks would become invalid because the hash of your block's merkle tree would no longer add up.
That being said, you may want to look into HD wallets. You could do something like this (see BIP44):
m / purpose' / coin_type' / account' / change / address_index
Here you can use an incrementing ID for account, so that each use has his own account. You can then create a new address for each incoming payment (change = 0 for inbound external transactions, change 1 = for change coming from your own wallet).
This means that each payment/whatever will have its own address. Because it's a HD wallet you can still access all the addresses with the master key if you like.
In my application I store users as user:n where n is a unique ID.
When a new user is created I increment a global variable such as user_count and use that ID as user:n.
But, I have an issue where I need to ensure an email is not already in use. I've done some reading around and the only way I can see how to do this is to:
1) Loop through the users. But, I am not keen on this solution as it could cause slower performance right?
2) Create a lookup that contains a list of email addresses used.
Both solutions seem a bit strange to me as I come from an SQL background.
Are these the only options available? I also have to do the same check for usernames too.
You could use Sets:
On registration: sadd taken_emails "john#example.com"
And testing with: sismember taken_emails "bob#exmaple.com"
Note that you have a possible race-condition where two users try to use the same email at the same time, both test and get "free" and then both register with it. You could use a lock to make sure they don't both get it, or make the registration operation atomic with either WATCH/MULTI/EXEC or with a lua script.
In my program, we store a user's IP address in a record. When we display a list of records to a user, we don't want to give away the other user's IP, so we SHA1 hash it. Then, when the user clicks on a record, it goes to a URL like this:
http://www.example.com/allrecordsbyipaddress.php?ipaddress=SHA1HASHOFTHEIPADDRESS
Now, I need to list all the records by the IP address specified in the SHA1 hash. I tried this:
SELECT * FROM records
WHERE SHA1(IPADDRESS)="da39a3ee5e6b4b0d3255bfef95601890afd80709"
but this does not work. How would I do this?
Thanks,
Isaac Waller
Don't know if it matters, but your SHA1 hash da39a3ee5e6b4b0d3255bfef95601890afd80709 is a well-known hash of an empty string.
Is it just an example or you forgot to provide an actual IP address to the hash calculation function?
Update:
Does your webpage code generate SHA1 hashes in lowercase?
This check will fail in MySQL:
SELECT SHA1('') = 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'
In this case, use this:
SELECT SHA1('') = LOWER('DA39A3EE5E6B4B0D3255BFEF95601890AFD80709')
, which will succeed.
Also, you can precalculate the SHA1 hash when you insert the records into the table:
INSERT
INTO ip_records (ip, ip_sha)
VALUES (#ip, SHA1(CONCAT('my_secret_salt', #ip))
SELECT *
FROM ip_records
WHERE ip_sha = #my_salted_sha1_from_webpage
This will return you the original IP and allow indexing of ip_sha, so that this query will work fast.
I'd store the SHA1 of the IP in the database along with the raw IP, so that the query would become
SELECT * FROM records WHERE ip_sha1 = "..."
Then I'd make sure that the SHA1 calculation happens exactly one place in code, so that there's no opportunity for it be be done slightly differently in multiple places. That also gives you the opportunity to mix a salt into the calculation, so that someone can't simply compute the SHA1 on an IP address they're interested in and pass that in by hand.
Storing the SHA1 hash the database also gives you the opportunity to add a secondary index on ip_sha1 to speed up that SELECT. If you have a very large data set, doing the SHA1 in the WHERE clauses forces the database to do a complete table scan, along with redoing a calculation for every record on every scan.
Every time I've had an unexpected hashing mismatch, it was because I accidentally hashed a string that included some whitespace, such as "\n".
Just a quick thought: that's a very simple obfuscation. There are only 232 possible IP addresses, so if somebody with technical knowledge wanted to figure it out, they could do that by calculating all 4 billion hashes, which wouldn't take very long. Depending on the sensitivity of those ip addresses, you may want to consider a private lookup table.
Did you compare the output of your hash algorithm with the output of MySQL's SHA1()? For example for IP address 1.2.3.4?
I ended up encrypting the IP addresses, and decrypting them on the other page. Then I can just use the raw IP address in the SQL query. Also, it protects against brute force attacks, like Autocracy said.