-
Notifications
You must be signed in to change notification settings - Fork 1
/
vanityAddr.scrypt
58 lines (46 loc) · 1.95 KB
/
vanityAddr.scrypt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import "ec.scrypt";
import "util.scrypt";
import "base58.scrypt";
contract VanityAddr {
static const int PUBKEY_UNCOMP_BYTES = 65;
bytes serializedPubKeys;
bytes pattern;
Ripemd160 cancelPubKeyHash;
public function cancel(Sig sig, PubKey pubKey) {
require(hash160(pubKey) == this.cancelPubKeyHash);
require(checkSig(sig, pubKey));
}
public function offerVanityAddr(PrivKey x,
PubKey X,
PubKey derivedPubKey,
int lambda,
int idxP,
SigHashPreimage txPreimage) {
// Check if x is private key of X.
require(Tx.checkPreimageAdvanced(txPreimage, x, X, Tx.invK, Tx.r, Tx.rBigEndian, SigHashType(SigHash.ALL | SigHash.FORKID)));
// Check if P' = P + X.
int start = idxP * PUBKEY_UNCOMP_BYTES;
int end = start + PUBKEY_UNCOMP_BYTES;
PubKey P = PubKey(this.serializedPubKeys[start:end]);
require(EC.isPubKeySum(P, X, lambda, derivedPubKey));
// Check if P' produces desired address.
PubKey derivedPubKeyCompressed = compressPubKey(derivedPubKey);
require(matchPattern(derivedPubKeyCompressed, this.pattern));
}
// Check if public key's address matches the given pattern.
static function matchPattern(PubKey pubKey, bytes pattern) : bool {
// Derive the address.
bytes addr = hash160(pubKey);
// Encode to base58check.
bytes addrB58 = Base58.base58EncodeCheckAddr(addr, Base58.P2PKH_verbyte_mainnet);
// Prefix match.
int l = len(pattern);
return addrB58[:l] == pattern;
}
static function compressPubKey(PubKey pk) : PubKey {
// Check if y-coord is even or odd
bool isEven = (pk[64:65] & b'01') != b'01';
bytes prefix = isEven ? b'02' : b'03';
return PubKey(prefix + pk[1:33]);
}
}