diff --git a/packages/binary/address/address.go b/packages/binary/address/address.go
index 41a03b74541434f3db9ae4b0b6374125f4a277dc..356a8e929522a23394dbd7cf4234bad4c9d8c9f9 100644
--- a/packages/binary/address/address.go
+++ b/packages/binary/address/address.go
@@ -3,6 +3,10 @@ package address
 import (
 	"crypto/rand"
 
+	"golang.org/x/crypto/blake2b"
+
+	"github.com/iotaledger/goshimmer/packages/binary/signature/ed25119"
+
 	"github.com/mr-tron/base58"
 )
 
@@ -24,6 +28,14 @@ func FromBase58EncodedString(base58EncodedString string) (result Address) {
 	return
 }
 
+func FromPublicKey(publicKey ed25119.PublicKey) (result Address) {
+	hashedPublicKey := blake2b.Sum256(publicKey[:])
+
+	copy(result[:], hashedPublicKey[:])
+
+	return
+}
+
 func Random() (result Address) {
 	addressBytes := make([]byte, Length)
 	if _, err := rand.Read(addressBytes); err != nil {
diff --git a/packages/binary/signature/ed25119/ed25119.go b/packages/binary/signature/ed25119/ed25119.go
new file mode 100644
index 0000000000000000000000000000000000000000..d4b65997bf4657ceeaa43427a8f0b43a58fc2dfe
--- /dev/null
+++ b/packages/binary/signature/ed25119/ed25119.go
@@ -0,0 +1,18 @@
+package ed25119
+
+import (
+	"crypto/rand"
+
+	"github.com/oasislabs/ed25519"
+)
+
+func GenerateKeyPair() (keyPair KeyPair) {
+	if public, private, err := ed25519.GenerateKey(rand.Reader); err != nil {
+		panic(err)
+	} else {
+		copy(keyPair.PrivateKey[:], private)
+		copy(keyPair.PublicKey[:], public)
+
+		return
+	}
+}
diff --git a/packages/binary/signature/ed25119/key_pair.go b/packages/binary/signature/ed25119/key_pair.go
new file mode 100644
index 0000000000000000000000000000000000000000..ad0c31bbe6ef5e06df08138dd66282e843322af4
--- /dev/null
+++ b/packages/binary/signature/ed25119/key_pair.go
@@ -0,0 +1,6 @@
+package ed25119
+
+type KeyPair struct {
+	PrivateKey PrivateKey
+	PublicKey  PublicKey
+}
diff --git a/packages/binary/signature/ed25119/private_key.go b/packages/binary/signature/ed25119/private_key.go
new file mode 100644
index 0000000000000000000000000000000000000000..89dc1a15ecc01f5b088a0aca871390dbbcbd101e
--- /dev/null
+++ b/packages/binary/signature/ed25119/private_key.go
@@ -0,0 +1,15 @@
+package ed25119
+
+import (
+	"github.com/oasislabs/ed25519"
+)
+
+type PrivateKey [PrivateKeySize]byte
+
+func (privateKey PrivateKey) Sign(data []byte) (result Signature) {
+	copy(result[:], ed25519.Sign(privateKey[:], data))
+
+	return
+}
+
+const PrivateKeySize = 64
diff --git a/packages/binary/signature/ed25119/public_key.go b/packages/binary/signature/ed25119/public_key.go
new file mode 100644
index 0000000000000000000000000000000000000000..c9d58e254413349234283406c817f8c68c7d30e5
--- /dev/null
+++ b/packages/binary/signature/ed25119/public_key.go
@@ -0,0 +1,25 @@
+package ed25119
+
+import (
+	"errors"
+
+	"github.com/oasislabs/ed25519"
+)
+
+type PublicKey [PublicKeySize]byte
+
+func (publicKey PublicKey) VerifySignature(data []byte, signature Signature) bool {
+	return ed25519.Verify(publicKey[:], data, signature[:])
+}
+
+func (publicKey *PublicKey) UnmarshalBinary(bytes []byte) (err error) {
+	if len(bytes) < PublicKeySize {
+		return errors.New("not enough bytes")
+	}
+
+	copy(publicKey[:], bytes[:])
+
+	return
+}
+
+const PublicKeySize = 32
diff --git a/packages/binary/signature/ed25119/signature.go b/packages/binary/signature/ed25119/signature.go
new file mode 100644
index 0000000000000000000000000000000000000000..bd33e1138e42da2809b0dac22afa1a140d5b8c3b
--- /dev/null
+++ b/packages/binary/signature/ed25119/signature.go
@@ -0,0 +1,19 @@
+package ed25119
+
+import (
+	"errors"
+)
+
+type Signature [SignatureSize]byte
+
+func (signature *Signature) UnmarshalBinary(bytes []byte) (err error) {
+	if len(bytes) < SignatureSize {
+		return errors.New("not enough bytes")
+	}
+
+	copy(signature[:], bytes[:])
+
+	return
+}
+
+const SignatureSize = 64
diff --git a/packages/binary/transaction/payload/valuetransfer/value.go b/packages/binary/transaction/payload/valuetransfer/value.go
deleted file mode 100644
index e433d9dfdf685b012760ea3b396659c616c80289..0000000000000000000000000000000000000000
--- a/packages/binary/transaction/payload/valuetransfer/value.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package valuetransfer
-
-import (
-	"sync"
-
-	"github.com/iotaledger/goshimmer/packages/binary/address"
-	"github.com/iotaledger/goshimmer/packages/binary/transaction/payload"
-	"github.com/iotaledger/goshimmer/packages/ledgerstate/transfer"
-)
-
-type ValueTransfer struct {
-	inputs      []*transfer.OutputReference
-	inputsMutex sync.RWMutex
-}
-
-var Type = payload.Type(1)
-
-func New() *ValueTransfer {
-	return &ValueTransfer{
-		inputs: make([]*transfer.OutputReference, 0),
-	}
-}
-
-func (valueTransfer *ValueTransfer) AddInput(transferHash transfer.Hash, address address.Address) *ValueTransfer {
-	valueTransfer.inputsMutex.Lock()
-	valueTransfer.inputs = append(valueTransfer.inputs, transfer.NewOutputReference(transferHash, address))
-	valueTransfer.inputsMutex.Unlock()
-
-	return valueTransfer
-}
-
-func (valueTransfer *ValueTransfer) GetType() payload.Type {
-	return Type
-}
-
-func (valueTransfer *ValueTransfer) MarshalBinary() (bytes []byte, err error) {
-	return
-}
-
-func (valueTransfer *ValueTransfer) UnmarshalBinary(bytes []byte) (err error) {
-	return
-}
diff --git a/packages/binary/transaction/payload/valuetransfer/valuetransfer.go b/packages/binary/transaction/payload/valuetransfer/valuetransfer.go
new file mode 100644
index 0000000000000000000000000000000000000000..6f369dc8883edb5259d6078de9192f5801c822a0
--- /dev/null
+++ b/packages/binary/transaction/payload/valuetransfer/valuetransfer.go
@@ -0,0 +1,362 @@
+package valuetransfer
+
+import (
+	"encoding/binary"
+	"sync"
+
+	"github.com/iotaledger/goshimmer/packages/binary/types"
+
+	"github.com/iotaledger/goshimmer/packages/binary/signature/ed25119"
+
+	"github.com/iotaledger/goshimmer/packages/ledgerstate/coloredcoins"
+
+	"github.com/iotaledger/goshimmer/packages/binary/address"
+	"github.com/iotaledger/goshimmer/packages/binary/transaction/payload"
+	"github.com/iotaledger/goshimmer/packages/ledgerstate/transfer"
+)
+
+type ValueTransfer struct {
+	inputs         []*transfer.OutputReference
+	outputs        map[address.Address][]*coloredcoins.ColoredBalance
+	signatures     map[ed25119.PublicKey]ed25119.Signature
+	payloadBytes   []byte
+	signatureBytes []byte
+
+	inputsMutex         sync.RWMutex
+	outputsMutex        sync.RWMutex
+	signaturesMutex     sync.RWMutex
+	payloadBytesMutex   sync.RWMutex
+	signatureBytesMutex sync.RWMutex
+}
+
+var Type = payload.Type(1)
+
+func New() *ValueTransfer {
+	return &ValueTransfer{
+		inputs:     make([]*transfer.OutputReference, 0),
+		outputs:    make(map[address.Address][]*coloredcoins.ColoredBalance),
+		signatures: make(map[ed25119.PublicKey]ed25119.Signature),
+	}
+}
+
+func (valueTransfer *ValueTransfer) GetType() payload.Type {
+	return Type
+}
+
+func (valueTransfer *ValueTransfer) AddInput(transferHash transfer.Hash, address address.Address) *ValueTransfer {
+	if valueTransfer.isFinalized() {
+		panic("you can not add inputs after you have started finalizing (sign / marshal) the ValueTransfer")
+	}
+
+	valueTransfer.inputsMutex.Lock()
+	valueTransfer.inputs = append(valueTransfer.inputs, transfer.NewOutputReference(transferHash, address))
+	valueTransfer.inputsMutex.Unlock()
+
+	return valueTransfer
+}
+
+func (valueTransfer *ValueTransfer) AddOutput(address address.Address, balance *coloredcoins.ColoredBalance) *ValueTransfer {
+	if valueTransfer.isFinalized() {
+		panic("you can not add outputs after you have started finalizing (sign / marshal) the ValueTransfer")
+	}
+
+	valueTransfer.outputsMutex.Lock()
+	if _, addressExists := valueTransfer.outputs[address]; !addressExists {
+		valueTransfer.outputs[address] = make([]*coloredcoins.ColoredBalance, 0)
+	}
+
+	valueTransfer.outputs[address] = append(valueTransfer.outputs[address], balance)
+	valueTransfer.outputsMutex.Unlock()
+
+	return valueTransfer
+}
+
+func (valueTransfer *ValueTransfer) Sign(keyPair ed25119.KeyPair) *ValueTransfer {
+	payloadBytes := valueTransfer.marshalPayloadBytes()
+
+	valueTransfer.signaturesMutex.RLock()
+	if _, signatureExists := valueTransfer.signatures[keyPair.PublicKey]; !signatureExists {
+		valueTransfer.signaturesMutex.RUnlock()
+
+		valueTransfer.signaturesMutex.Lock()
+		if _, signatureExists := valueTransfer.signatures[keyPair.PublicKey]; !signatureExists {
+			valueTransfer.signatures[keyPair.PublicKey] = keyPair.PrivateKey.Sign(payloadBytes)
+		}
+		valueTransfer.signaturesMutex.Unlock()
+	} else {
+		valueTransfer.signaturesMutex.RUnlock()
+	}
+
+	return valueTransfer
+}
+
+func (valueTransfer *ValueTransfer) VerifySignatures() bool {
+	_, _ = valueTransfer.MarshalBinary()
+	payloadBytes := valueTransfer.marshalPayloadBytes()
+
+	addressesToSign := make(map[address.Address]types.Empty)
+	for _, input := range valueTransfer.inputs {
+		addressesToSign[input.GetAddress()] = types.Void
+	}
+
+	for publicKey, signature := range valueTransfer.signatures {
+		if publicKey.VerifySignature(payloadBytes, signature) {
+			delete(addressesToSign, address.FromPublicKey(publicKey))
+		} else {
+			panic("INVALID SIGNATURE")
+		}
+	}
+
+	return len(addressesToSign) == 0
+}
+
+func (valueTransfer *ValueTransfer) MarshalBinary() (result []byte, err error) {
+	payloadBytes := valueTransfer.marshalPayloadBytes()
+	signatureBytes := valueTransfer.marshalSignatureBytes(payloadBytes)
+
+	result = append(payloadBytes, signatureBytes...)
+
+	return
+}
+
+func (valueTransfer *ValueTransfer) UnmarshalBinary(bytes []byte) (err error) {
+	offset := 0
+
+	payloadBytesOffset := offset
+	if err = valueTransfer.unmarshalInputs(bytes, &offset); err != nil {
+		return
+	}
+
+	if err = valueTransfer.unmarshalOutputs(bytes, &offset); err != nil {
+		return
+	}
+
+	payloadBytesLength := offset - payloadBytesOffset
+	valueTransfer.payloadBytes = make([]byte, payloadBytesLength)
+	copy(valueTransfer.payloadBytes, bytes[payloadBytesOffset:payloadBytesOffset+payloadBytesLength])
+
+	signatureBytesOffset := offset
+	if err = valueTransfer.unmarshalSignatures(bytes, &offset); err != nil {
+		return
+	}
+
+	signatureBytesLength := offset - signatureBytesOffset
+	valueTransfer.signatureBytes = make([]byte, signatureBytesLength)
+	copy(valueTransfer.signatureBytes, bytes[signatureBytesOffset:signatureBytesOffset+signatureBytesLength])
+
+	return
+}
+
+func (valueTransfer *ValueTransfer) isFinalized() (result bool) {
+	valueTransfer.payloadBytesMutex.RLock()
+	result = valueTransfer.payloadBytes != nil
+	valueTransfer.payloadBytesMutex.RUnlock()
+
+	return
+}
+
+func (valueTransfer *ValueTransfer) marshalPayloadBytes() (result []byte) {
+	valueTransfer.payloadBytesMutex.RLock()
+	if valueTransfer.payloadBytes == nil {
+		valueTransfer.payloadBytesMutex.RUnlock()
+
+		valueTransfer.payloadBytesMutex.Lock()
+		if valueTransfer.payloadBytes == nil {
+			result = append(valueTransfer.marshalInputs(), valueTransfer.marshalOutputs()...)
+
+			valueTransfer.payloadBytes = result
+		} else {
+			result = valueTransfer.payloadBytes
+		}
+		valueTransfer.payloadBytesMutex.Unlock()
+	} else {
+		result = valueTransfer.payloadBytes
+
+		valueTransfer.payloadBytesMutex.RUnlock()
+	}
+
+	return
+}
+
+func (valueTransfer *ValueTransfer) marshalInputs() (result []byte) {
+	inputCount := len(valueTransfer.inputs)
+	marshaledTransferOutputReferenceLength := transfer.HashLength + address.Length
+
+	result = make([]byte, 4+inputCount*marshaledTransferOutputReferenceLength)
+	offset := 0
+
+	binary.LittleEndian.PutUint32(result[offset:], uint32(inputCount))
+	offset += 4
+
+	for _, transferOutputReference := range valueTransfer.inputs {
+		if marshaledTransferOutputReference, err := transferOutputReference.MarshalBinary(); err != nil {
+			panic(err)
+		} else {
+			copy(result[offset:], marshaledTransferOutputReference)
+			offset += marshaledTransferOutputReferenceLength
+		}
+	}
+
+	return
+}
+
+func (valueTransfer *ValueTransfer) marshalOutputs() (result []byte) {
+	totalLength := 4
+	for _, outputs := range valueTransfer.outputs {
+		totalLength += address.Length
+
+		totalLength += 4
+
+		for range outputs {
+			totalLength += coloredcoins.ColorLength + 8
+		}
+	}
+
+	result = make([]byte, totalLength)
+	offset := 0
+
+	binary.LittleEndian.PutUint32(result[offset:], uint32(len(valueTransfer.outputs)))
+	offset += 4
+
+	for outputAddress, outputs := range valueTransfer.outputs {
+		copy(result[offset:], outputAddress[:])
+		offset += address.Length
+
+		binary.LittleEndian.PutUint32(result[offset:], uint32(len(outputs)))
+		offset += 4
+
+		for _, coloredBalance := range outputs {
+			if marshaledColoredBalance, marshalErr := coloredBalance.MarshalBinary(); marshalErr != nil {
+				panic(marshalErr)
+			} else {
+				copy(result[offset:], marshaledColoredBalance)
+				offset += coloredcoins.ColorLength + 8
+			}
+		}
+	}
+
+	return
+}
+
+func (valueTransfer *ValueTransfer) marshalSignatureBytes(payloadBytes []byte) (result []byte) {
+	valueTransfer.signatureBytesMutex.RLock()
+	if valueTransfer.signatureBytes == nil {
+		valueTransfer.signatureBytesMutex.RUnlock()
+
+		valueTransfer.signatureBytesMutex.Lock()
+		if valueTransfer.signatureBytes == nil {
+			signatureCount := len(valueTransfer.signatures)
+			result = make([]byte, 4+signatureCount*(ed25119.PublicKeySize+ed25119.SignatureSize))
+			offset := 0
+
+			binary.LittleEndian.PutUint32(result[offset:], uint32(signatureCount))
+			offset += 4
+
+			valueTransfer.signaturesMutex.RLock()
+			for publicKey, signature := range valueTransfer.signatures {
+				copy(result[offset:], publicKey[:])
+				offset += ed25119.PublicKeySize
+
+				copy(result[offset:], signature[:])
+				offset += ed25119.SignatureSize
+			}
+			valueTransfer.signaturesMutex.RUnlock()
+
+			valueTransfer.signatureBytes = result
+		} else {
+			result = valueTransfer.signatureBytes
+		}
+		valueTransfer.signatureBytesMutex.Unlock()
+	} else {
+		result = valueTransfer.signatureBytes
+
+		valueTransfer.signatureBytesMutex.RUnlock()
+	}
+
+	return
+}
+
+func (valueTransfer *ValueTransfer) unmarshalInputs(bytes []byte, offset *int) (err error) {
+	inputCount := int(binary.LittleEndian.Uint32(bytes[*offset:]))
+	*offset += 4
+
+	valueTransfer.inputs = make([]*transfer.OutputReference, inputCount)
+	marshaledTransferOutputReferenceLength := transfer.HashLength + address.Length
+	for i := 0; i < inputCount; i++ {
+		var transferOutputReference transfer.OutputReference
+		if err = transferOutputReference.UnmarshalBinary(bytes[*offset:]); err != nil {
+			return
+		}
+		*offset += marshaledTransferOutputReferenceLength
+
+		valueTransfer.inputs[i] = &transferOutputReference
+	}
+
+	return
+}
+
+func (valueTransfer *ValueTransfer) unmarshalOutputs(bytes []byte, offset *int) (err error) {
+	outputCount := int(binary.LittleEndian.Uint32(bytes[*offset:]))
+	*offset += 4
+
+	valueTransfer.outputs = make(map[address.Address][]*coloredcoins.ColoredBalance)
+
+	for i := 0; i < outputCount; i++ {
+		var outputAddress address.Address
+		if err = outputAddress.UnmarshalBinary(bytes[*offset:]); err != nil {
+			return
+		}
+		*offset += address.Length
+
+		outputsCount := int(binary.LittleEndian.Uint32(bytes[*offset:]))
+		*offset += 4
+
+		valueTransfer.outputs[outputAddress] = make([]*coloredcoins.ColoredBalance, outputsCount)
+
+		for j := 0; j < outputsCount; j++ {
+			var coloredBalance coloredcoins.ColoredBalance
+			if err = coloredBalance.UnmarshalBinary(bytes[*offset:]); err != nil {
+				return
+			}
+			*offset += coloredcoins.BalanceLength
+
+			valueTransfer.outputs[outputAddress][j] = &coloredBalance
+		}
+	}
+
+	return
+}
+
+func (valueTransfer *ValueTransfer) unmarshalSignatures(bytes []byte, offset *int) (err error) {
+	signatureCount := int(binary.LittleEndian.Uint32(bytes[*offset:]))
+	*offset += 4
+
+	valueTransfer.signatures = make(map[ed25119.PublicKey]ed25119.Signature)
+
+	for i := 0; i < signatureCount; i++ {
+		var publicKey ed25119.PublicKey
+		if err = publicKey.UnmarshalBinary(bytes[*offset:]); err != nil {
+			return
+		}
+		*offset += ed25119.PublicKeySize
+
+		var signature ed25119.Signature
+		if err = signature.UnmarshalBinary(bytes[*offset:]); err != nil {
+			return
+		}
+		*offset += ed25119.SignatureSize
+
+		valueTransfer.signatures[publicKey] = signature
+	}
+
+	return
+}
+
+func init() {
+	payload.RegisterType(Type, func(data []byte) (payload payload.Payload, err error) {
+		payload = &ValueTransfer{}
+		err = payload.UnmarshalBinary(data)
+
+		return
+	})
+}
diff --git a/packages/binary/transaction/test/transaction_test.go b/packages/binary/transaction/test/transaction_test.go
index 06e790d6761a21e71438630069256e3eb7a43202..a5443cd193d706f4229a8ca59ca8909a8987f966 100644
--- a/packages/binary/transaction/test/transaction_test.go
+++ b/packages/binary/transaction/test/transaction_test.go
@@ -5,6 +5,10 @@ import (
 	"sync"
 	"testing"
 
+	"github.com/iotaledger/goshimmer/packages/binary/signature/ed25119"
+
+	"github.com/iotaledger/goshimmer/packages/ledgerstate/coloredcoins"
+
 	"github.com/panjf2000/ants/v2"
 
 	"github.com/iotaledger/goshimmer/packages/ledgerstate/transfer"
@@ -49,16 +53,26 @@ func TestNew(t *testing.T) {
 	newTransaction1 := transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(), data.New([]byte("test")))
 	assert.Equal(t, newTransaction1.VerifySignature(), true)
 
-	valueTransfer := valuetransfer.New().AddInput(transfer.NewHash("test"), address.Random())
+	keyPairOfSourceAddress := ed25119.GenerateKeyPair()
+	keyPairOfTargetAddress := ed25119.GenerateKeyPair()
 
-	newValueTransaction1 := transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(), valueTransfer)
+	newValueTransaction1 := transaction.New(transaction.EmptyId, transaction.EmptyId, identity.Generate(),
+		valuetransfer.New().
+			AddInput(transfer.NewHash("test"), address.FromPublicKey(keyPairOfSourceAddress.PublicKey)).
+			AddOutput(address.FromPublicKey(keyPairOfTargetAddress.PublicKey), coloredcoins.NewColoredBalance(coloredcoins.NewColor("IOTA"), 12)).
+			Sign(keyPairOfSourceAddress),
+	)
 	assert.Equal(t, newValueTransaction1.VerifySignature(), true)
 
 	newValueTransaction2, _ := transaction.FromBytes(newValueTransaction1.GetBytes())
 	assert.Equal(t, newValueTransaction2.VerifySignature(), true)
 
-	if newValueTransaction1.GetPayload().GetType() == valuetransfer.Type {
-		fmt.Println("VALUE TRANSFER TRANSACTION")
+	fmt.Println(newValueTransaction1.GetPayload().(*valuetransfer.ValueTransfer).MarshalBinary())
+	fmt.Println(newValueTransaction2.GetPayload().(*valuetransfer.ValueTransfer).MarshalBinary())
+
+	if newValueTransaction2.GetPayload().GetType() == valuetransfer.Type {
+		fmt.Println(newValueTransaction1.GetPayload().(*valuetransfer.ValueTransfer).VerifySignatures())
+		fmt.Println(newValueTransaction2.GetPayload().(*valuetransfer.ValueTransfer).VerifySignatures())
 	}
 
 	newTransaction2 := transaction.New(newTransaction1.GetId(), transaction.EmptyId, identity.Generate(), data.New([]byte("test1")))
diff --git a/packages/ledgerstate/coloredcoins/color.go b/packages/ledgerstate/coloredcoins/color.go
index 9ff9559400132de925c58fcb0ccf7b40bc0b2d37..e5cc8321421d7efc70edf1a16f8b6a1e9d5a3924 100644
--- a/packages/ledgerstate/coloredcoins/color.go
+++ b/packages/ledgerstate/coloredcoins/color.go
@@ -14,6 +14,13 @@ func NewColor(color string) (result Color) {
 	return
 }
 
+func (color *Color) MarshalBinary() (result []byte, err error) {
+	result = make([]byte, ColorLength)
+	copy(result, color[:])
+
+	return
+}
+
 func (color *Color) UnmarshalBinary(data []byte) error {
 	copy(color[:], data[:ColorLength])
 
diff --git a/packages/ledgerstate/coloredcoins/colored_balance.go b/packages/ledgerstate/coloredcoins/colored_balance.go
index 898a0d9a58840220b64c0a0513925173796f0160..845b39c7783f87ac4d6543e577eb0e850a9aa03b 100644
--- a/packages/ledgerstate/coloredcoins/colored_balance.go
+++ b/packages/ledgerstate/coloredcoins/colored_balance.go
@@ -17,21 +17,37 @@ func NewColoredBalance(color Color, balance uint64) *ColoredBalance {
 	}
 }
 
-func (balance *ColoredBalance) GetColor() Color {
-	return balance.color
+func (coloredBalance *ColoredBalance) GetColor() Color {
+	return coloredBalance.color
 }
 
-func (balance *ColoredBalance) GetBalance() uint64 {
-	return balance.balance
+func (coloredBalance *ColoredBalance) GetBalance() uint64 {
+	return coloredBalance.balance
 }
 
-func (balance *ColoredBalance) UnmarshalBinary(data []byte) error {
-	balance.color = Color{}
-	if err := balance.color.UnmarshalBinary(data); err != nil {
+func (coloredBalance *ColoredBalance) MarshalBinary() (result []byte, err error) {
+	result = make([]byte, ColorLength+8)
+
+	if marshaledColor, marshalErr := coloredBalance.color.MarshalBinary(); marshalErr != nil {
+		err = marshalErr
+
+		return
+	} else {
+		copy(result, marshaledColor)
+	}
+
+	binary.LittleEndian.PutUint64(result[ColorLength:], coloredBalance.balance)
+
+	return
+}
+
+func (coloredBalance *ColoredBalance) UnmarshalBinary(data []byte) error {
+	coloredBalance.color = Color{}
+	if err := coloredBalance.color.UnmarshalBinary(data); err != nil {
 		return err
 	}
 
-	balance.balance = binary.LittleEndian.Uint64(data[ColorLength:])
+	coloredBalance.balance = binary.LittleEndian.Uint64(data[ColorLength:])
 
 	return nil
 }
diff --git a/packages/ledgerstate/outputs.png b/packages/ledgerstate/outputs.png
index 348a7350b16b3d38a6d4731c7c51f2740fe6110c..fbc282cfbfb8ee744230710f46f058f8ff961ccd 100644
Binary files a/packages/ledgerstate/outputs.png and b/packages/ledgerstate/outputs.png differ
diff --git a/packages/ledgerstate/outputs1.png b/packages/ledgerstate/outputs1.png
index b695948cae29c186c1eb156ee1b0a736ab1045f6..639f9f9d70d5ff3d49ec4cfb86fd919dc28fe008 100644
Binary files a/packages/ledgerstate/outputs1.png and b/packages/ledgerstate/outputs1.png differ
diff --git a/packages/ledgerstate/outputs2.png b/packages/ledgerstate/outputs2.png
index 1628d4989b63e5a01f961b83453c40dd02db4996..b3de946340e39640db58e60567793234cea900ef 100644
Binary files a/packages/ledgerstate/outputs2.png and b/packages/ledgerstate/outputs2.png differ
diff --git a/packages/ledgerstate/transfer/output_reference.go b/packages/ledgerstate/transfer/output_reference.go
index bbdcef2f5555d6717b564e700294c6ad4f00317e..b061af8fb30545da6772b0be535943be65d9a33c 100644
--- a/packages/ledgerstate/transfer/output_reference.go
+++ b/packages/ledgerstate/transfer/output_reference.go
@@ -19,6 +19,33 @@ func NewOutputReference(transferHash Hash, addressHash address.Address) *OutputR
 	}
 }
 
+func (reference *OutputReference) GetAddress() address.Address {
+	return reference.addressHash
+}
+
+func (reference *OutputReference) MarshalBinary() (result []byte, err error) {
+	result = make([]byte, HashLength+address.Length)
+	offset := 0
+
+	copy(result[offset:], reference.transferHash[:])
+	offset += HashLength
+
+	copy(result[offset:], reference.addressHash[:])
+
+	return
+}
+
+func (reference *OutputReference) UnmarshalBinary(bytes []byte) (err error) {
+	offset := 0
+
+	copy(reference.transferHash[:], bytes[offset:])
+	offset += HashLength
+
+	copy(reference.addressHash[:], bytes[offset:])
+
+	return
+}
+
 func (reference *OutputReference) GetStorageKey() []byte {
 	return reference.storageKey
 }