Exemplo n.º 1
0
// Hash returns the hash of this builder's transaction.
func (b *TransactionBuilder) Hash() ([32]byte, error) {
	var txBytes bytes.Buffer

	_, err := fmt.Fprint(&txBytes, b.NetworkID)
	if err != nil {
		return [32]byte{}, err
	}

	_, err = xdr.Marshal(&txBytes, xdr.EnvelopeTypeEnvelopeTypeTx)
	if err != nil {
		return [32]byte{}, err
	}

	_, err = xdr.Marshal(&txBytes, b.TX)
	if err != nil {
		return [32]byte{}, err
	}

	return stellarbase.Hash(txBytes.Bytes()), nil
}
Exemplo n.º 2
0
func TestDecode(t *testing.T) {
	Convey("Decode XDR Enum", t, func() {
		// works for positive values
		var op xdr.OperationType
		r := bytes.NewReader([]byte{0x00, 0x00, 0x00, 0x00})
		xdr.Unmarshal(r, &op)
		So(op, ShouldEqual, xdr.OperationTypeCreateAccount)

		r = bytes.NewReader([]byte{0x00, 0x00, 0x00, 0x08})
		xdr.Unmarshal(r, &op)
		So(op, ShouldEqual, xdr.OperationTypeAccountMerge)

		// works for negative values
		var trc xdr.TransactionResultCode
		r = bytes.NewReader([]byte{0xFF, 0xFF, 0xFF, 0xFF})
		xdr.Unmarshal(r, &trc)
		So(trc, ShouldEqual, xdr.TransactionResultCodeTxFailed)

		r = bytes.NewReader([]byte{0x00, 0xFF, 0xFF, 0xFF})
		_, err := xdr.Unmarshal(r, &op)
		So(err, ShouldNotBeNil)
	})

	Convey("Decodes Memo", t, func() {
		data := "AAAAAA=="
		rawr := strings.NewReader(data)
		b64r := base64.NewDecoder(base64.StdEncoding, rawr)

		var memo xdr.Memo

		_, err := xdr.Unmarshal(b64r, &memo)

		So(err, ShouldBeNil)
	})

	Convey("Decodes AccountID", t, func() {
		data := "AAAAAK6jei3jmoI8TGlD/egc37PXtHKKzWV8wViZBaCu5L5M"
		rawr := strings.NewReader(data)
		b64r := base64.NewDecoder(base64.StdEncoding, rawr)

		var id xdr.AccountId
		_, err := xdr.Unmarshal(b64r, &id)

		So(err, ShouldBeNil)
	})

	Convey("Decodes OperationBody", t, func() {
		data := "AAAAAAAAAACuo3ot45qCPExpQ/3oHN+z17Ryis1lfMFYmQWgruS+TAAAAAA7msoA"
		rawr := strings.NewReader(data)
		b64r := base64.NewDecoder(base64.StdEncoding, rawr)

		var body xdr.OperationBody
		_, err := xdr.Unmarshal(b64r, &body)

		So(err, ShouldBeNil)
	})

	Convey("Decode TransactionResultPair", t, func() {
		data := "mf13Xm7tPjMcffhLVA2VXbTs6fV9IpgHFZGKy3zlu/QAAAAAAAAACgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA=="
		rawr := strings.NewReader(data)
		b64r := base64.NewDecoder(base64.StdEncoding, rawr)

		var trp xdr.TransactionResultPair
		_, err := xdr.Unmarshal(b64r, &trp)

		So(err, ShouldBeNil)
		So(len(trp.TransactionHash), ShouldEqual, 32)
		So(trp.Result.FeeCharged, ShouldEqual, 10)

		trr := trp.Result.Result
		So(trr.Code, ShouldEqual, xdr.TransactionResultCodeTxSuccess)

		So(trr.Results, ShouldNotBeNil)

		r := trr.MustResults()
		So(len(r), ShouldEqual, 1)

		opr := r[0]
		So(opr.Code, ShouldEqual, xdr.OperationResultCodeOpInner)

		oprr := opr.MustTr()
		So(oprr.Type, ShouldEqual, xdr.OperationTypeCreateAccount)

		cr := oprr.MustCreateAccountResult()
		So(cr.Code, ShouldEqual, xdr.CreateAccountResultCodeCreateAccountSuccess)

		So(func() {
			oprr.MustAccountMergeResult()
		}, ShouldPanic)
	})

	Convey("Decode TransactionEnvelope", t, func() {
		data := "AAAAAGL8HQvQkbK2HA3WVjRrKmjX00fG8sLI7m0ERwJW/AX3AAAACgAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAArqN6LeOagjxMaUP96Bzfs9e0corNZXzBWJkFoK7kvkwAAAAAO5rKAAAAAAAAAAABVvwF9wAAAEAKZ7IPj/46PuWU6ZOtyMosctNAkXRNX9WCAI5RnfRk+AyxDLoDZP/9l3NvsxQtWj9juQOuoBlFLnWu8intgxQA"
		rawr := strings.NewReader(data)
		b64r := base64.NewDecoder(base64.StdEncoding, rawr)

		var txe xdr.TransactionEnvelope
		_, err := xdr.Unmarshal(b64r, &txe)

		So(err, ShouldBeNil)
		So(len(txe.Signatures), ShouldEqual, 1)

		tx := txe.Tx

		So(tx.Fee, ShouldEqual, 10)
		So(tx.SeqNum, ShouldEqual, 1)

		So(tx.Memo.Type, ShouldEqual, xdr.MemoTypeMemoNone)

		op := tx.Operations[0]

		So(op.SourceAccount, ShouldBeNil)

		p := op.Body.MustCreateAccountOp()
		So(p.StartingBalance, ShouldEqual, 1000000000)
	})

	Convey("Decode TransactionMeta", t, func() {
		data := "AAAAAAAAAAEAAAABAAAAAgAAAAAAAAAAYvwdC9CRsrYcDdZWNGsqaNfTR8bywsjubQRHAlb8BfcBY0V4XYn/9gAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAAAAAACAAAAAAAAAACuo3ot45qCPExpQ/3oHN+z17Ryis1lfMFYmQWgruS+TAAAAAA7msoAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAAAAAABi/B0L0JGythwN1lY0aypo19NHxvLCyO5tBEcCVvwF9wFjRXgh7zX2AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA=="
		rawr := strings.NewReader(data)
		b64r := base64.NewDecoder(base64.StdEncoding, rawr)

		var m xdr.TransactionMeta
		_, err := xdr.Unmarshal(b64r, &m)

		So(err, ShouldBeNil)
		tm := m.MustV0()
		So(len(tm.Changes), ShouldEqual, 1)
		So(len(tm.Operations), ShouldEqual, 1)
		So(len(tm.Operations[0].Changes), ShouldEqual, 2)
	})

	Convey("Roundtrip TransactionEnvelope", t, func() {
		data := "AAAAAGL8HQvQkbK2HA3WVjRrKmjX00fG8sLI7m0ERwJW/AX3AAAACgAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAArqN6LeOagjxMaUP96Bzfs9e0corNZXzBWJkFoK7kvkwAAAAAO5rKAAAAAAAAAAABVvwF9wAAAEAKZ7IPj/46PuWU6ZOtyMosctNAkXRNX9WCAI5RnfRk+AyxDLoDZP/9l3NvsxQtWj9juQOuoBlFLnWu8intgxQA"
		rawr := strings.NewReader(data)
		b64r := base64.NewDecoder(base64.StdEncoding, rawr)

		var txe xdr.TransactionEnvelope
		n, err := xdr.Unmarshal(b64r, &txe)
		So(err, ShouldBeNil)

		var output bytes.Buffer
		b64w := base64.NewEncoder(base64.StdEncoding, &output)

		n2, err := xdr.Marshal(b64w, txe)

		So(n2, ShouldEqual, n)
		So(output.String(), ShouldEqual, data)
	})
}
Exemplo n.º 3
0
// ExampleLowLevelTransaction creates and signs a simple transaction, and then
// encodes it into a hex string capable of being submitted to stellar-core.
//
// It uses the low-level xdr facilities to create the transaction.
func ExampleLowLevelTransaction() {
	spub, spriv, err := GenerateKeyFromSeed("SA26PHIKZM6CXDGR472SSGUQQRYXM6S437ZNHZGRM6QA4FOPLLLFRGDX")

	if err != nil {
		panic(err)
	}

	dpub, _, err := GenerateKeyFromSeed("SBQHO2IMYKXAYJFCWGXC7YKLJD2EGDPSK3IUDHVJ6OOTTKLSCK6Z6POM")

	if err != nil {
		panic(err)
	}

	asset, err := xdr.NewAsset(xdr.AssetTypeAssetTypeNative, nil)
	if err != nil {
		panic(err)
	}

	destination, err := AddressToAccountId(dpub.Address())
	if err != nil {
		panic(err)
	}

	op := xdr.PaymentOp{
		Destination: destination,
		Asset:       asset,
		Amount:      50 * 10000000,
	}

	memo, err := xdr.NewMemo(xdr.MemoTypeMemoNone, nil)

	source, err := AddressToAccountId(spub.Address())
	if err != nil {
		panic(err)
	}

	body, err := xdr.NewOperationBody(xdr.OperationTypePayment, op)
	if err != nil {
		panic(err)
	}

	tx := xdr.Transaction{
		SourceAccount: source,
		Fee:           10,
		SeqNum:        xdr.SequenceNumber(1),
		Memo:          memo,
		Operations: []xdr.Operation{
			{Body: body},
		},
	}

	var txBytes bytes.Buffer
	_, err = xdr.Marshal(&txBytes, tx)
	if err != nil {
		panic(err)
	}

	txHash := Hash(txBytes.Bytes())
	signature := spriv.Sign(txHash[:])

	ds := xdr.DecoratedSignature{
		Hint:      spriv.Hint(),
		Signature: xdr.Signature(signature[:]),
	}

	txe := xdr.TransactionEnvelope{
		Tx:         tx,
		Signatures: []xdr.DecoratedSignature{ds},
	}

	var txeBytes bytes.Buffer
	_, err = xdr.Marshal(&txeBytes, txe)
	if err != nil {
		panic(err)
	}
	txeB64 := base64.StdEncoding.EncodeToString(txeBytes.Bytes())

	fmt.Printf("tx base64: %s", txeB64)
	// Output: tx base64: AAAAAAU08yUQ8sHqhY8j9mXWwERfHC/3cKFSe/spAr0rGtO2AAAACgAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAA+fnTe7/v4whpBUx96oj92jfZPz7S00l3O2xeyeqWIA0AAAAAAAAAAB3NZQAAAAAAAAAAATXnnQoAAABAieruUIGcQH6RlQ+prYflPFU3nED2NvWhtaC+tgnKsqgiKURK4xo/W7EgH0+I6aQok52awbE+ksOxEQ5MLJ9eAw==
}