Skip to content

Commit

Permalink
bech32 support
Browse files Browse the repository at this point in the history
Allow to specify a JSON serialized condition using bech32 encoding.

resolve #362
  • Loading branch information
husio committed Mar 18, 2019
1 parent 6fa1cdc commit cacf444
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 1 deletion.
9 changes: 9 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"regexp"
"strings"

"github.com/iov-one/weave/crypto/bech32"
"github.com/iov-one/weave/errors"
)

Expand Down Expand Up @@ -166,6 +167,13 @@ func (a *Address) UnmarshalJSON(raw []byte) error {
}
*a = c.Address()
return nil
case "bech32":
_, addr, err := bech32.Decode(enc)
if err != nil {
return errors.Wrapf(err, "deserialize bech32: %s", err)
}
*a = addr
return nil
default:
return errors.ErrInvalidType.Newf("unknown format %q", chunks[0])
}
Expand Down
7 changes: 6 additions & 1 deletion conditions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ func TestAddressUnmarshalJSON(t *testing.T) {
json: `"cond:foo/bar/636f6e646974696f6e64617461"`,
wantAddr: weave.NewCondition("foo", "bar", []byte("conditiondata")).Address(),
},
"bech32 decoding": {
// $ bech32 -e -h tiov 746573742d7061796c6f6164
json: `"bech32:tiov1w3jhxapdwpshjmr0v9jqymqq4y"`,
wantAddr: weave.Address("test-payload"),
},
"invalid condition format": {
json: `"cond:foo/636f6e646974696f6e64617461"`,
wantErr: errors.ErrInvalidInput,
Expand Down Expand Up @@ -80,7 +85,7 @@ func TestAddressUnmarshalJSON(t *testing.T) {
t.Fatalf("got error: %+v", err)
}
if err == nil && !reflect.DeepEqual(a, tc.wantAddr) {
t.Fatalf("got address: %q", a)
t.Fatalf("got address: %q (want %q)", a, tc.wantAddr)
}
})
}
Expand Down
33 changes: 33 additions & 0 deletions crypto/bech32/bech32.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package bech32

import (
"github.com/btcsuite/btcutil/bech32"
"github.com/iov-one/weave/errors"
)

// Decode converts given bech32 encoded representation into raw payload and a
// human readable part.
func Decode(raw string) (string, []byte, error) {
hrp, payload, err := bech32.Decode(raw)
if err != nil {
return "", nil, errors.Wrap(err, "bech32 decode")
}
payload, err = bech32.ConvertBits(payload, 5, 8, false)
if err != nil {
return "", nil, errors.Wrap(err, "convert bits")
}
return hrp, payload, nil
}

// Encode converts given bytes into bech32 encoded representation.
func Encode(hrp string, payload []byte) ([]byte, error) {
payload, err := bech32.ConvertBits(payload, 8, 5, true)
if err != nil {
return nil, errors.Wrap(err, "convert bits")
}
raw, err := bech32.Encode(hrp, payload)
if err != nil {
return nil, errors.Wrap(err, "bech32 encode")
}
return []byte(raw), nil
}
37 changes: 37 additions & 0 deletions crypto/bech32/bech32_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package bech32

import (
"bytes"
"encoding/hex"
"testing"
)

func TestBench32EncodeDecode(t *testing.T) {
// bech32 -e -h tiov 746573742d7061796c6f6164
const enc = `tiov1w3jhxapdwpshjmr0v9jqymqq4y`

want, err := hex.DecodeString("746573742d7061796c6f6164")
if err != nil {
t.Fatal(err)
}

hrp, payload, err := Decode(enc)
if err != nil {
t.Fatal(err)
}

if !bytes.Equal(want, payload) {
t.Logf("want %d", want)
t.Logf("got %d", payload)
t.Fatal("invalid decode")
}

raw, err := Encode(hrp, payload)
if err != nil {
t.Fatalf("cannot encode: %s", err)
}

if string(raw) != enc {
t.Fatalf("invalid encoding: %q", raw)
}
}

0 comments on commit cacf444

Please sign in to comment.