github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/wallet/regenerate_test.go (about) 1 package wallet 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os" 7 "path/filepath" 8 "testing" 9 10 "github.com/nspcc-dev/neo-go/pkg/core/state" 11 "github.com/nspcc-dev/neo-go/pkg/crypto/keys" 12 "github.com/nspcc-dev/neo-go/pkg/encoding/address" 13 "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" 14 "github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" 15 "github.com/stretchr/testify/require" 16 ) 17 18 const regenerate = false 19 20 const dockerWalletDir = "../../.docker/wallets/" 21 22 var ( 23 // privNetKeys is a list of unencrypted WIFs sorted by wallet number. 24 privnetWIFs = []string{ 25 "KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY", 26 "KzfPUYDC9n2yf4fK5ro4C8KMcdeXtFuEnStycbZgX3GomiUsvX6W", 27 "L2oEXKRAAMiPEZukwR5ho2S6SMeQLhcK9mF71ZnF7GvT8dU4Kkgz", 28 "KzgWE3u3EDp13XPXXuTKZxeJ3Gi8Bsm8f9ijY3ZsCKKRvZUo1Cdn", 29 } 30 31 passwords = []string{"one", "two", "three", "four"} 32 33 // naiveScrypt is naive scrypt parameters used for testing wallets to save 34 // time on accounts decryption. 35 naiveScrypt = keys.ScryptParams{N: 2, R: 1, P: 1} 36 ) 37 38 func getKeys(t *testing.T) []*keys.PublicKey { 39 var pubs []*keys.PublicKey 40 41 for i := range privnetWIFs { 42 priv, err := keys.NewPrivateKeyFromWIF(privnetWIFs[i]) 43 require.NoError(t, err) 44 pubs = append(pubs, priv.PublicKey()) 45 } 46 return pubs 47 } 48 49 func getNEP2Account(t *testing.T, wif, pass string) *Account { 50 return getAccountWithScrypt(t, wif, pass, keys.NEP2ScryptParams()) 51 } 52 53 func getTestingAccount(t *testing.T, wif, pass string) *Account { 54 return getAccountWithScrypt(t, wif, pass, naiveScrypt) 55 } 56 57 func getAccountWithScrypt(t *testing.T, wif, pass string, scrypt keys.ScryptParams) *Account { 58 acc, err := NewAccountFromWIF(wif) 59 require.NoError(t, err) 60 require.NoError(t, acc.Encrypt(pass, scrypt)) 61 return acc 62 } 63 64 func TestRegenerateSoloWallet(t *testing.T) { 65 if !regenerate { 66 return 67 } 68 walletPath := filepath.Join(dockerWalletDir, "wallet1_solo.json") 69 wif := privnetWIFs[0] 70 acc1 := getNEP2Account(t, wif, "one") 71 acc2 := getNEP2Account(t, wif, "one") 72 require.NoError(t, acc2.ConvertMultisig(3, getKeys(t))) 73 74 acc3 := getNEP2Account(t, wif, "one") 75 require.NoError(t, acc3.ConvertMultisig(1, keys.PublicKeys{getKeys(t)[0]})) 76 77 createNEP2Wallet(t, walletPath, acc1, acc2, acc3) 78 } 79 80 func regenerateWallets(t *testing.T, dir string) { 81 pubs := getKeys(t) 82 for i := range privnetWIFs { 83 acc1 := getNEP2Account(t, privnetWIFs[i], passwords[i]) 84 acc2 := getNEP2Account(t, privnetWIFs[i], passwords[i]) 85 require.NoError(t, acc2.ConvertMultisig(3, pubs)) 86 87 createNEP2Wallet(t, filepath.Join(dir, fmt.Sprintf("wallet%d.json", i+1)), acc1, acc2) 88 } 89 } 90 91 func TestRegeneratePrivnetWallets(t *testing.T) { 92 if !regenerate { 93 return 94 } 95 dirs := []string{ 96 dockerWalletDir, 97 "../consensus/testdata", 98 } 99 for i := range dirs { 100 regenerateWallets(t, dirs[i]) 101 } 102 } 103 104 func TestRegenerateWalletTestdata(t *testing.T) { 105 if !regenerate { 106 return 107 } 108 const walletDir = "./testdata/" 109 110 acc1 := getTestingAccount(t, privnetWIFs[0], "one") 111 acc2 := getTestingAccount(t, privnetWIFs[0], "one") 112 pubs := getKeys(t) 113 require.NoError(t, acc2.ConvertMultisig(3, pubs)) 114 115 acc3 := getTestingAccount(t, privnetWIFs[1], "two") 116 acc3.Default = true 117 118 createTestingWallet(t, filepath.Join(walletDir, "wallet1.json"), acc1, acc2) 119 120 createTestingWallet(t, filepath.Join(walletDir, "wallet2.json"), acc1, acc2, acc3) 121 } 122 123 func TestRegenerateNotaryWallets(t *testing.T) { 124 if !regenerate { 125 return 126 } 127 const ( 128 acc1WIF = "L1MstxuD8SvS9HuFcV5oYzcdA1xX8D9bD9qPwg8fU5SSywYBecg3" 129 acc2WIF = "L2iGxPvxbyWpYEbCZk2L3PgT7sCQaSDAbBC4MRLAjhs1s2JZ1xs5" 130 acc3WIF = "L1xD2yiUyARX8DAkWa8qGpWpwjqW2u717VzUJyByk6s7HinhRVZv" 131 acc4WIF = "L1ioz93TNt6Nu1aoMpZQ4zgdtgC8ZvJMC6pyHFkrovdR3SFwbn6n" 132 ) 133 var walletDir = filepath.Join("..", "services", "notary", "testdata") 134 acc1 := getAccountWithScrypt(t, acc1WIF, "one", naiveScrypt) 135 acc2 := getAccountWithScrypt(t, acc2WIF, "one", naiveScrypt) 136 acc3 := getAccountWithScrypt(t, acc3WIF, "four", naiveScrypt) 137 createTestingWallet(t, filepath.Join(walletDir, "notary1.json"), acc1, acc2, acc3) 138 139 acc4 := getAccountWithScrypt(t, acc4WIF, "two", naiveScrypt) 140 createTestingWallet(t, filepath.Join(walletDir, "notary2.json"), acc4) 141 } 142 143 func TestRegenerateOracleWallets(t *testing.T) { 144 if !regenerate { 145 return 146 } 147 const ( 148 walletDir = "../services/oracle/testdata/" 149 acc1WIF = "L38E2tRktb2kWc5j3Kx6Cg3ifVoi4DHhpVZrQormEFTT92C4iSUa" 150 acc2WIF = "KyA8z2MyLCSjJFG3F4SUp85CZ4WJm4qgWihFJZFEDYGEyw8oGcEP" 151 ) 152 153 acc1 := getTestingAccount(t, acc1WIF, "one") 154 createTestingWallet(t, filepath.Join(walletDir, "oracle1.json"), acc1) 155 156 acc2 := getTestingAccount(t, acc2WIF, "two") 157 createTestingWallet(t, filepath.Join(walletDir, "oracle2.json"), acc2) 158 } 159 160 func TestRegenerateExamplesWallet(t *testing.T) { 161 if !regenerate { 162 return 163 } 164 const ( 165 walletPath = "../../examples/my_wallet.json" 166 acc1WIF = "L46dn46AMZY7NQGZHemAdgcMabKon85eme45hgQkAUQBiRacY8MB" 167 ) 168 169 acc1 := getNEP2Account(t, acc1WIF, "qwerty") 170 acc1.Label = "my_account" 171 createNEP2Wallet(t, walletPath, acc1) 172 } 173 174 func TestRegenerateCLITestwallet(t *testing.T) { 175 if !regenerate { 176 return 177 } 178 const ( 179 walletPath = "../../cli/testdata/testwallet.json" 180 accWIF = "L23LrQNWELytYLvb5c6dXBDdF2DNPL9RRNWPqppv3roxacSnn8CN" 181 ) 182 183 acc := getAccountWithScrypt(t, accWIF, "testpass", naiveScrypt) 184 acc.Label = "kek" 185 createTestingWallet(t, walletPath, acc) 186 } 187 188 func TestRegenerateCLITestwalletMulti(t *testing.T) { 189 if !regenerate { 190 return 191 } 192 const ( 193 walletPath = "../../cli/testdata/testwallet_multi.json" 194 accWIF1 = "L2NZQ84s8SuUfyJmtjs7J5a2pZFEVQVVRYDtNsQEyB4RjHnpkorr" 195 pass1 = "one" 196 accWIF2 = "L4pSqPmvbghcM8NY14CNSUzkK92VmSFLKNwAh9TqLqFhTZkxZgsP" 197 pass2 = "two" 198 accWIF3 = "L1eNtPQA8bALqvSgGMNpNR3EYFR15WeNdCZDuiwWYcQ6Q6FfuVro" 199 pass3 = "three" 200 ) 201 202 acc1 := getAccountWithScrypt(t, accWIF1, pass1, naiveScrypt) 203 acc1.Label = pass1 204 acc2 := getAccountWithScrypt(t, accWIF2, pass2, naiveScrypt) 205 acc2.Label = pass2 206 acc3 := getAccountWithScrypt(t, accWIF3, pass3, naiveScrypt) 207 acc3.Label = pass3 208 createTestingWallet(t, walletPath, acc1, acc2, acc3) 209 } 210 211 func TestRegenerateCLITestwallet_NEO3(t *testing.T) { 212 if !regenerate { 213 return 214 } 215 const walletPath = "../../cli/wallet/testdata/testwallet_NEO3.json" 216 217 pubs := getKeys(t) 218 acc1 := getNEP2Account(t, privnetWIFs[0], passwords[0]) 219 acc2 := getNEP2Account(t, privnetWIFs[0], passwords[0]) 220 require.NoError(t, acc2.ConvertMultisig(3, pubs)) 221 createNEP2Wallet(t, walletPath, acc1, acc2) 222 } 223 224 // createNEP2Wallet creates wallet with provided accounts and NEP2 scrypt parameters. 225 func createNEP2Wallet(t *testing.T, path string, accs ...*Account) { 226 createWallet(t, path, keys.NEP2ScryptParams(), accs...) 227 } 228 229 // createTestingWallet creates wallet with provided accounts and scrypt parameters with 230 // low values which can be used for testing to save time on accounts decryption. 231 func createTestingWallet(t *testing.T, path string, accs ...*Account) { 232 createWallet(t, path, naiveScrypt, accs...) 233 } 234 235 func createWallet(t *testing.T, path string, scryptParams keys.ScryptParams, accs ...*Account) { 236 w, err := NewWallet(path) 237 require.NoError(t, err) 238 w.Scrypt = scryptParams 239 240 if len(accs) == 0 { 241 t.Fatal("provide at least 1 account") 242 } 243 for _, acc := range accs { 244 w.AddAccount(acc) 245 } 246 require.NoError(t, w.SavePretty()) 247 } 248 249 func TestRegenerateCLIWallet1_solo(t *testing.T) { 250 if !regenerate { 251 return 252 } 253 const ( 254 walletPath = "../../cli/testdata/wallet1_solo.json" 255 verifyWIF = "L3W8gi36Y3KPqyR54VJaE1agH9yPvW2hALNZy1BerDwWce9P9xEy" 256 verifyNEFPath = "../../cli/smartcontract/testdata/verify.nef" 257 verifyManifestPath = "../../cli/smartcontract/testdata/verify.manifest.json" 258 ) 259 260 wif := privnetWIFs[0] 261 acc1 := getAccountWithScrypt(t, wif, "one", naiveScrypt) 262 acc1.Default = true 263 acc2 := getAccountWithScrypt(t, wif, "one", naiveScrypt) 264 require.NoError(t, acc2.ConvertMultisig(3, getKeys(t))) 265 266 acc3 := getAccountWithScrypt(t, wif, "one", naiveScrypt) 267 require.NoError(t, acc3.ConvertMultisig(1, keys.PublicKeys{getKeys(t)[0]})) 268 269 acc4 := getAccountWithScrypt(t, verifyWIF, "pass", naiveScrypt) // deployed verify.go contract 270 f, err := os.ReadFile(verifyNEFPath) 271 require.NoError(t, err) 272 nefFile, err := nef.FileFromBytes(f) 273 require.NoError(t, err) 274 manifestBytes, err := os.ReadFile(verifyManifestPath) 275 require.NoError(t, err) 276 m := &manifest.Manifest{} 277 require.NoError(t, json.Unmarshal(manifestBytes, m)) 278 hash := state.CreateContractHash(acc3.PrivateKey().GetScriptHash(), nefFile.Checksum, m.Name) 279 acc4.Address = address.Uint160ToString(hash) 280 acc4.Contract = &Contract{ 281 Script: nefFile.Script, 282 Deployed: true, 283 Parameters: []ContractParam{}, 284 } 285 acc4.Label = "verify" 286 createTestingWallet(t, walletPath, acc1, acc2, acc3, acc4) 287 }