-
Notifications
You must be signed in to change notification settings - Fork 0
/
address.go
128 lines (104 loc) · 2.9 KB
/
address.go
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package ergo
/*
#include "ergo.h"
*/
import "C"
import (
"runtime"
"unsafe"
)
type networkPrefix uint8
const (
// MainnetPrefix is the network prefix used in mainnet address encoding
MainnetPrefix networkPrefix = 0
// TestnetPrefix is the network prefix used in testnet address encoding
TestnetPrefix = 16
)
type addressTypePrefix uint8
const (
// P2PkPrefix 0x01 - Pay-to-PublicKey(P2PK) address
P2PkPrefix addressTypePrefix = 1
// Pay2ShPrefix 0x02 - Pay-to-Script-Hash(P2SH)
Pay2ShPrefix addressTypePrefix = 2
// Pay2SPrefix 0x03 - Pay-to-Script(P2S)
Pay2SPrefix addressTypePrefix = 3
)
type Address interface {
// Base58 converts an Address to a base58 string using the provided networkPrefix.
Base58(prefix networkPrefix) string
// TypePrefix returns the addressTypePrefix for the Address.
// 0x01 - Pay-to-PublicKey(P2PK) address.
// 0x02 - Pay-to-Script-Hash(P2SH).
// 0x03 - Pay-to-Script(P2S).
TypePrefix() addressTypePrefix
// Tree returns the Address as Tree
Tree() Tree
pointer() C.AddressPtr
}
type address struct {
p C.AddressPtr
}
func newAddress(a *address) Address {
runtime.SetFinalizer(a, finalizeAddress)
return a
}
// NewAddress creates an Address from a base58 string.
func NewAddress(s string) (Address, error) {
addressStr := C.CString(s)
defer C.free(unsafe.Pointer(addressStr))
var p C.AddressPtr
errPtr := C.ergo_lib_address_from_base58(addressStr, &p)
err := newError(errPtr)
if err.isError() {
return nil, err.error()
}
a := &address{p}
return newAddress(a), nil
}
// NewAddressFromTree creates a new Address from supplied Tree
func NewAddressFromTree(tree Tree) (Address, error) {
var p C.AddressPtr
errPtr := C.ergo_lib_address_from_ergo_tree(tree.pointer(), &p)
err := newError(errPtr)
if err.isError() {
return nil, err.error()
}
a := &address{p}
return newAddress(a), nil
}
// NewAddressFromPublicKey creates a new Address from public key bytes
func NewAddressFromPublicKey(publicKey []byte) (Address, error) {
byteData := C.CBytes(publicKey)
defer C.free(unsafe.Pointer(byteData))
var p C.AddressPtr
errPtr := C.ergo_lib_address_from_public_key((*C.uchar)(byteData), C.uintptr_t(len(publicKey)), &p)
err := newError(errPtr)
if err.isError() {
return nil, err.error()
}
a := &address{p: p}
return newAddress(a), nil
}
func (a *address) Base58(prefix networkPrefix) string {
var outAddrStr *C.char
cPrefix := C.uchar(prefix)
C.ergo_lib_address_to_base58(a.p, cPrefix, &outAddrStr)
defer C.ergo_lib_delete_string(outAddrStr)
return C.GoString(outAddrStr)
}
func (a *address) TypePrefix() addressTypePrefix {
prefix := C.ergo_lib_address_type_prefix(a.p)
return addressTypePrefix(prefix)
}
func (a *address) Tree() Tree {
var p C.ErgoTreePtr
C.ergo_lib_address_to_ergo_tree(a.p, &p)
t := &tree{p: p}
return newTree(t)
}
func (a *address) pointer() C.AddressPtr {
return a.p
}
func finalizeAddress(a *address) {
C.ergo_lib_address_delete(a.p)
}