Typos should not lead to loss of funds


Hey ZIL team, I stumbled upon a post on reddit where the usability of current blockchain tech has been discussed, especially how the fear of typos when entering the receivers address might hinder adoption for less tech savvy people.

Of course there are some simple checks you could perform to verify the correctness of the entered address (e.g. checksums, address book, ENS like services, check if address was used before, etc.) but all these checks happen BEFORE hitting the send button. Also some of these checks still require the user to check the address at least once very carefully, which IMO is not user friendly and nevertheless still prone to errors. So what can be done to ensure that the funds are not sent to some random (but somehow still valid) address by mistake AFTER the user hits the send button?

One idea I found pretty interesting was the proposal to require the receiver to manually confirm the transaction he/she receives. And if he/she does not confirm the transaction within a certain period of time, the funds (maybe minus some return tx fees) will be sent back automatically. This way, even if a user accidentically sends funds to a random address, he/she can be sure that the funds will be returned to him/her after some time.

I’m aware that requiring every receiver to manually confirm each incoming transaction is quite impractical, but a simple solution for this could be to allow a user to ‘unlock‘ his/her address so that from that moment on every incoming transaction would be confirmed automatically (e.g. one could let users unlock their addresses when they create their wallet). This way, only ‘inactive‘ addresses will need confirmations.

A drawback to this approach could be that all addresses would need to be initialized as smart contract addresses. At least that‘s how I would try to implement this feature (but I’m no expert so maybe there are other ways to do it?). This way, ‘confirmation‘ and ‘unlock‘ could be realized as simple function calls to the smart contract. This would also mean that tx fees will be higher, but I still think that the advantages of a feature like this would definitely outweigh the drawbacks (especially since tx fees in ZIL are magnitudes lower than for example in ETH) and help with mass adoption of blockchain tech.

Are there other major drawbacks I didn’t think of? I would be very glad to hear your opinions on this, especially from the ZIL team regarding whether a feature like this could be implemented for ZIL in the future.



That is certainly possible in Scilla, Zilliqa’s smart contract language. You can do so like this:

  • User A (ByStr20) sends funds (Uint128) to User B (ByStr20) by depositing the fund in the smart contract which has a timer measured in block number (BNum).
field timed_deposit : Map ByStr20 (Map ByStr20 (Pair BNum Uint128)) = Emp ByStr20 (Map ByStr20 (Pair BNum Uint128)
  • User B will need to withdraw the fund deposited by User A before the timer, or block height is more than what was set by the User A.
(*Check if timer is over*)
current_block <- & BLOCKNUMBER;
check_deadline = builtin blt userA_set_block_timer current_block;
match check_deadline with
| True =>
(*User B can withdraw funds that User A deposited*)
| False =>
(*User B cannot withdraw funds, User A can retrieve deposit*)

You can find out more about Scilla in the documentations and try it out in the web IDE.



Thanks for your reply Han, good to hear that it’s possible with Scilla. But more importantly is the question if it is feasible to realize it on protocol level because such a feature would only make sense if all ZIL addresses are initialzed as smart contract addresses from the start by default.



It can be argued that this feature is not necessarily a good idea. One basic reason being that the recipient has to be online. Imagine yourself receiving a one-time payment for a service rendered while you are not online for whatever reasons (say because your are holidaying in Italy). In such scenarios, it is possible that you may miss your payment. Yes, the sender can always re-initiate another transfer, but it may become painful if the sender has to make several of such payments where more than one recipient failed to acknowledge the payment transfer.

Having said that, there is a solution to make the solution work natively, i.e., at the protocol-level. It will require some changes to the transaction field and transaction validation. Each transaction will have a default lock-time T (the block height after which the transaction is annulled). T can also be set to a non-default value by the sender. Once, the transaction is sent to the network, nodes will verify the validity of the transaction. Apart from the usual checks with the nonce value, the balance of the sender etc, miners will check if the current blockheight is smaller than or equal to T. If these checks pass, then the miner will issue an event that the recipient can listen to. Note that the miner does not update the state of the accounts of the sender and the recipient yet. Any transaction from the same sender could be blocked until the blockheight T+1.

Now, once the recipient observes the event, it will have to send another transaction of a special type (say confirmation transaction) referencing the sender’s first transaction. If this new transaction gets mined before the block height T+1, then, the account balance of the sender and the recipient can be updated. If not, the first transaction is annulled.

I have left out the details of the validation for the second transaction, but this should explain the main idea of how to support this natively using some special transaction types and fields and special validation checks.



Thanks for your response @maqstica.

Your concerns are certainly valid. I also thought that this would be very impractical so I tried to come up with a solution for this myself:

Do you think this idea would be feasible?



I would prefer personally not to do this at the protocol layer, but at the smart contract layer. Say if I have a smart contract that sends many User addresses funds, all Users will need to white-list the sender’s address before being able to receive funds when this is implemented at the protocol layer. This could make use-cases that require several levels of contract calls before sending a User funds (e.g Contract A calls Contract B calls Contract C send funds to User A) very much a hassle.



What t0nic90 wants can partly be realized by introducing longer Zilliqa account address with some CRC/parity checks. It can be as simple as additional 1, 2 or even 4 characters added as prefix or suffix to the account address. The wallet would accept both forms but longer form would be recommended for people.

One might use Hamming code to construct the extended Zilliqa address.



Address checksum is implemented in the protocol level. All Zilliqa transaction’s toAddr field has to be checksummed to the 6*ith bit, else it will be rejected as invalid.

You can see an example here: https://apidocs.zilliqa.com/#createtransaction