From 2c5366f2599682a431a31eec22de4220b475227c Mon Sep 17 00:00:00 2001 From: Ryo Onodera Date: Wed, 26 Aug 2020 01:13:12 +0900 Subject: [PATCH] Document how to validate account pubkey (#11821) --- docs/src/integrations/exchange.md | 71 +++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/docs/src/integrations/exchange.md b/docs/src/integrations/exchange.md index e9df6b2eb..a83d49a95 100644 --- a/docs/src/integrations/exchange.md +++ b/docs/src/integrations/exchange.md @@ -100,6 +100,77 @@ greater security. If so, you will need to move SOL to hot accounts using our When a user wants to deposit SOL into your exchange, instruct them to send a transfer to the appropriate deposit address. +## Validating User-supplied Account Addresses for Withdrawals in SOL + +As withdrawals are irreversible, it may be a good practice to validate the +account address before authorizing withdrawals into user-supplied accounts +to prevent accidental user's fund loss. + +For a normal account in Solana, its address is simply a Base58-encoded +actual 256-bit public key of ed25519. Because not all bit pattern is a valid +public key for the ed25519, it's possible to make sure user-supplied +account addresses are at least something that may be a correct ed25519 public +key. + +### Java + +You can check Solana's normal account address validity by first decoding +Base58 string and ensuring the decoded bytes are valid ed25519 public keys +like this: + +The following code sample assumes you're using the Maven. + +`pom.xml`: + +```xml + + ... + + spring + https://repo.spring.io/libs-release/ + + + +... + + + ... + + io.github.novacrypto + Base58 + 0.1.3 + + + cafe.cryptography + curve25519-elisabeth + 0.1.0 + + +``` + +```java +import io.github.novacrypto.base58.Base58; +import cafe.cryptography.curve25519.CompressedEdwardsY; + +public class PubkeyValidator +{ + public static boolean verifyPubkey(String userProvidedPubkey) + { + try { + return _verifyPubkeyInternal(userProvidedPubkey); + } catch (Exception e) { + return false; + } + } + + public static boolean _verifyPubkeyInternal(String maybePubkey) throws Exception + { + byte[] bytes = Base58.base58Decode(maybePubkey); + return !(new CompressedEdwardsY(bytes)).decompress().isSmallOrder(); + } +} +``` + ### Poll for Blocks The easiest way to track all the deposit accounts for your exchange is to poll