diff --git a/packages/binary/tangle/model/transaction/transaction.go b/packages/binary/tangle/model/transaction/transaction.go
index de18ffc47ed6514c4883dc1382da60d23184d758..227b30954db9086f9f640dcf954bdaa7c44c9ffe 100644
--- a/packages/binary/tangle/model/transaction/transaction.go
+++ b/packages/binary/tangle/model/transaction/transaction.go
@@ -273,5 +273,6 @@ func (transaction *Transaction) String() string {
 		stringify.StructField("id", base58.Encode(transactionId[:])),
 		stringify.StructField("trunkTransactionId", base58.Encode(transaction.trunkTransactionId[:])),
 		stringify.StructField("trunkTransactionId", base58.Encode(transaction.branchTransactionId[:])),
+		stringify.StructField("payload", transaction.payload),
 	)
 }
diff --git a/packages/binary/valuetransfers/address.go b/packages/binary/valuetransfers/address.go
deleted file mode 100644
index ecf5f38739da463d601b2682eb13d38710f3490f..0000000000000000000000000000000000000000
--- a/packages/binary/valuetransfers/address.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package valuetransfers
-
-import (
-	"github.com/mr-tron/base58"
-)
-
-type AddressVersion = byte
-
-type AddressDigest = []byte
-
-type Address [AddressLength]byte
-
-func NewAddress(bytes []byte) (address Address) {
-	copy(address[:], bytes)
-
-	return
-}
-
-func (address *Address) GetVersion() AddressVersion {
-	return address[0]
-}
-
-func (address *Address) GetDigest() AddressDigest {
-	return address[1:]
-}
-
-func (address Address) ToBytes() []byte {
-	return address[:]
-}
-
-func (address Address) String() string {
-	return "Address(" + base58.Encode(address.ToBytes()) + ")"
-}
-
-const AddressLength = 33
diff --git a/packages/binary/valuetransfers/payload/transfer/address/address.go b/packages/binary/valuetransfers/address/address.go
similarity index 100%
rename from packages/binary/valuetransfers/payload/transfer/address/address.go
rename to packages/binary/valuetransfers/address/address.go
diff --git a/packages/binary/valuetransfers/color.go b/packages/binary/valuetransfers/color.go
deleted file mode 100644
index 29150eb215d1b8a6a00467944cf9038969c0eb7c..0000000000000000000000000000000000000000
--- a/packages/binary/valuetransfers/color.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package valuetransfers
-
-import (
-	"github.com/mr-tron/base58"
-
-	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
-)
-
-type Color [ColorLength]byte
-
-func ColorFromBytes(bytes []byte) (result Color, err error, consumedBytes int) {
-	colorBytes, err := marshalutil.New(bytes).ReadBytes(ColorLength)
-	if err != nil {
-		return
-	}
-	copy(result[:], colorBytes)
-
-	consumedBytes = ColorLength
-
-	return
-}
-
-const ColorLength = 32
-
-func (color Color) Bytes() []byte {
-	return color[:]
-}
-
-func (color Color) String() string {
-	if color == COLOR_IOTA {
-		return "IOTA"
-	}
-
-	return base58.Encode(color[:])
-}
-
-var COLOR_IOTA Color = [32]byte{}
diff --git a/packages/binary/valuetransfers/coloredbalance.go b/packages/binary/valuetransfers/coloredbalance.go
deleted file mode 100644
index 2a9a5f6620fac323c784e7d4c4f26e9a1ecd640a..0000000000000000000000000000000000000000
--- a/packages/binary/valuetransfers/coloredbalance.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package valuetransfers
-
-import (
-	"strconv"
-
-	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
-)
-
-type ColoredBalance struct {
-	color   Color
-	balance int64
-}
-
-func NewColoredBalance(color Color, balance int64) (result *ColoredBalance) {
-	result = &ColoredBalance{
-		color:   color,
-		balance: balance,
-	}
-
-	return
-}
-
-func ColoredBalanceFromBytes(bytes []byte) (result *ColoredBalance, err error, consumedBytes int) {
-	result = &ColoredBalance{}
-
-	marshalUtil := marshalutil.New(bytes)
-
-	if color, colorErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) {
-		return ColorFromBytes(data)
-	}); colorErr != nil {
-		return nil, colorErr, marshalUtil.ReadOffset()
-	} else {
-		result.color = color.(Color)
-	}
-
-	result.balance, err = marshalUtil.ReadInt64()
-	if err != nil {
-		return
-	}
-
-	consumedBytes = marshalUtil.ReadOffset()
-
-	return
-}
-
-func (balance *ColoredBalance) ToBytes() []byte {
-	marshalUtil := marshalutil.New(ColorLength + marshalutil.UINT32_SIZE)
-
-	marshalUtil.WriteBytes(balance.color.Bytes())
-	marshalUtil.WriteInt64(balance.balance)
-
-	return marshalUtil.Bytes()
-}
-
-func (balance *ColoredBalance) String() string {
-	return strconv.FormatInt(balance.balance, 10) + " " + balance.color.String()
-}
diff --git a/packages/binary/valuetransfers/payload/transfer/coloredbalance/color/color.go b/packages/binary/valuetransfers/coloredbalance/color/color.go
similarity index 90%
rename from packages/binary/valuetransfers/payload/transfer/coloredbalance/color/color.go
rename to packages/binary/valuetransfers/coloredbalance/color/color.go
index a06aa5536462519ec0c33236854fb99fbd5cd3cc..5afcc6915849ad52e53c4b31a814797225b935a0 100644
--- a/packages/binary/valuetransfers/payload/transfer/coloredbalance/color/color.go
+++ b/packages/binary/valuetransfers/coloredbalance/color/color.go
@@ -27,11 +27,11 @@ func (color Color) Bytes() []byte {
 }
 
 func (color Color) String() string {
-	if color == COLOR_IOTA {
+	if color == IOTA {
 		return "IOTA"
 	}
 
 	return base58.Encode(color[:])
 }
 
-var COLOR_IOTA Color = [32]byte{}
+var IOTA Color = [32]byte{}
diff --git a/packages/binary/valuetransfers/payload/transfer/coloredbalance/coloredbalance.go b/packages/binary/valuetransfers/coloredbalance/coloredbalance.go
similarity index 74%
rename from packages/binary/valuetransfers/payload/transfer/coloredbalance/coloredbalance.go
rename to packages/binary/valuetransfers/coloredbalance/coloredbalance.go
index 1cae2c86ef6178b58c18b5b0df0453375c81f8cb..26b0a485207480e384c52f644299daf5c55649a3 100644
--- a/packages/binary/valuetransfers/payload/transfer/coloredbalance/coloredbalance.go
+++ b/packages/binary/valuetransfers/coloredbalance/coloredbalance.go
@@ -4,15 +4,15 @@ import (
 	"strconv"
 
 	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
-	color2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/coloredbalance/color"
+	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/coloredbalance/color"
 )
 
 type ColoredBalance struct {
-	color   color2.Color
+	color   color.Color
 	balance int64
 }
 
-func New(color color2.Color, balance int64) (result *ColoredBalance) {
+func New(color color.Color, balance int64) (result *ColoredBalance) {
 	result = &ColoredBalance{
 		color:   color,
 		balance: balance,
@@ -27,11 +27,11 @@ func FromBytes(bytes []byte) (result *ColoredBalance, err error, consumedBytes i
 	marshalUtil := marshalutil.New(bytes)
 
 	if coinColor, colorErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) {
-		return color2.FromBytes(data)
+		return color.FromBytes(data)
 	}); colorErr != nil {
 		return nil, colorErr, marshalUtil.ReadOffset()
 	} else {
-		result.color = coinColor.(color2.Color)
+		result.color = coinColor.(color.Color)
 	}
 
 	result.balance, err = marshalUtil.ReadInt64()
@@ -45,7 +45,7 @@ func FromBytes(bytes []byte) (result *ColoredBalance, err error, consumedBytes i
 }
 
 func (balance *ColoredBalance) ToBytes() []byte {
-	marshalUtil := marshalutil.New(color2.Length + marshalutil.UINT32_SIZE)
+	marshalUtil := marshalutil.New(color.Length + marshalutil.UINT32_SIZE)
 
 	marshalUtil.WriteBytes(balance.color.Bytes())
 	marshalUtil.WriteInt64(balance.balance)
diff --git a/packages/binary/valuetransfers/outputs.go b/packages/binary/valuetransfers/outputs.go
deleted file mode 100644
index a672469734932ad92b33edb285845054bdd98444..0000000000000000000000000000000000000000
--- a/packages/binary/valuetransfers/outputs.go
+++ /dev/null
@@ -1,154 +0,0 @@
-package valuetransfers
-
-import (
-	"github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap"
-	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
-)
-
-type Outputs struct {
-	*orderedmap.OrderedMap
-}
-
-func NewOutputs(outputs map[Address][]*ColoredBalance) (result *Outputs) {
-	result = &Outputs{orderedmap.New()}
-	for address, balances := range outputs {
-		result.Add(address, balances)
-	}
-
-	return
-}
-
-// OutputsFromBytes reads the bytes and unmarshals the given information into an *Outputs object. It either creates a
-// new object, or uses the optional object provided in the arguments.
-func OutputsFromBytes(bytes []byte, optionalTargetObject ...*Outputs) (result *Outputs, err error, consumedBytes int) {
-	// determine the target object that will hold the unmarshaled information
-	switch len(optionalTargetObject) {
-	case 0:
-		result = &Outputs{orderedmap.New()}
-	case 1:
-		result = optionalTargetObject[0]
-	default:
-		panic("too many arguments in call to OutputFromBytes")
-	}
-
-	// initialize helper
-	marshalUtil := marshalutil.New(bytes)
-
-	// read number of addresses in the outputs
-	addressCount, addressCountErr := marshalUtil.ReadUint32()
-	if addressCountErr != nil {
-		err = addressCountErr
-
-		return
-	}
-
-	// iterate the corresponding times and collect addresses + their details
-	for i := uint32(0); i < addressCount; i++ {
-		// read address
-		addressBytes, addressErr := marshalUtil.ReadBytes(AddressLength)
-		if addressErr != nil {
-			err = addressErr
-
-			return
-		}
-		address := NewAddress(addressBytes)
-
-		// read number of balances in the outputs
-		balanceCount, balanceCountErr := marshalUtil.ReadUint32()
-		if balanceCountErr != nil {
-			err = balanceCountErr
-
-			return
-		}
-
-		// iterate the corresponding times and collect balances
-		coloredBalances := make([]*ColoredBalance, balanceCount)
-		for j := uint32(0); j < balanceCount; j++ {
-			coloredBalance, coloredBalanceErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return ColoredBalanceFromBytes(data) })
-			if coloredBalanceErr != nil {
-				err = coloredBalanceErr
-
-				return
-			}
-
-			coloredBalances[j] = coloredBalance.(*ColoredBalance)
-		}
-
-		// add the gathered information as an output
-		result.Add(address, coloredBalances)
-	}
-
-	// return the number of bytes we processed
-	consumedBytes = marshalUtil.ReadOffset()
-
-	return
-}
-
-func (outputs *Outputs) Add(address Address, balances []*ColoredBalance) *Outputs {
-	outputs.Set(address, balances)
-
-	return outputs
-}
-
-func (outputs *Outputs) ForEach(consumer func(address Address, balances []*ColoredBalance)) {
-	outputs.OrderedMap.ForEach(func(key, value interface{}) bool {
-		consumer(key.(Address), value.([]*ColoredBalance))
-
-		return true
-	})
-}
-
-func (outputs *Outputs) Bytes() []byte {
-	marshalUtil := marshalutil.New()
-
-	if outputs == nil {
-		marshalUtil.WriteUint32(0)
-
-		return marshalUtil.Bytes()
-	}
-
-	marshalUtil.WriteUint32(uint32(outputs.Size()))
-	outputs.ForEach(func(address Address, balances []*ColoredBalance) {
-		marshalUtil.WriteBytes(address.ToBytes())
-		marshalUtil.WriteUint32(uint32(len(balances)))
-
-		for _, balance := range balances {
-			marshalUtil.WriteBytes(balance.ToBytes())
-		}
-	})
-
-	return marshalUtil.Bytes()
-}
-
-func (outputs *Outputs) String() string {
-	if outputs == nil {
-		return "<nil>"
-	}
-
-	result := "[\n"
-	empty := true
-	outputs.ForEach(func(address Address, balances []*ColoredBalance) {
-		empty = false
-
-		result += "    " + address.String() + ": [\n"
-
-		balancesEmpty := true
-		for _, balance := range balances {
-			balancesEmpty = false
-
-			result += "        " + balance.String() + ",\n"
-		}
-
-		if balancesEmpty {
-			result += "        <empty>\n"
-		}
-
-		result += "    ]\n"
-	})
-
-	if empty {
-		result += "    <empty>\n"
-	}
-
-	return result + "]"
-}
diff --git a/packages/binary/valuetransfers/payload.go b/packages/binary/valuetransfers/payload.go
deleted file mode 100644
index f613b37d0997b46a27d144dab962bfdea9df7d39..0000000000000000000000000000000000000000
--- a/packages/binary/valuetransfers/payload.go
+++ /dev/null
@@ -1,186 +0,0 @@
-package valuetransfers
-
-import (
-	"sync"
-
-	"github.com/iotaledger/hive.go/objectstorage"
-	"golang.org/x/crypto/blake2b"
-
-	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
-	"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload"
-)
-
-type Payload struct {
-	objectstorage.StorableObjectFlags
-
-	id              *PayloadId
-	trunkPayloadId  PayloadId
-	branchPayloadId PayloadId
-	transfer        *Transfer
-	bytes           []byte
-
-	idMutex    sync.RWMutex
-	bytesMutex sync.RWMutex
-}
-
-func NewPayload(trunkPayloadId, branchPayloadId PayloadId, valueTransfer *Transfer) *Payload {
-	return &Payload{
-		trunkPayloadId:  trunkPayloadId,
-		branchPayloadId: branchPayloadId,
-		transfer:        valueTransfer,
-	}
-}
-
-func (payload *Payload) GetId() PayloadId {
-	// acquire lock for reading id
-	payload.idMutex.RLock()
-
-	// return if id has been calculated already
-	if payload.id != nil {
-		defer payload.idMutex.RUnlock()
-
-		return *payload.id
-	}
-
-	// switch to write lock
-	payload.idMutex.RUnlock()
-	payload.idMutex.Lock()
-	defer payload.idMutex.Unlock()
-
-	// return if id has been calculated in the mean time
-	if payload.id != nil {
-		return *payload.id
-	}
-
-	// otherwise calculate the id
-	transferId := payload.GetTransfer().GetId()
-	marshalUtil := marshalutil.New(PayloadIdLength + PayloadIdLength + TransferIdLength)
-	marshalUtil.WriteBytes(payload.trunkPayloadId[:])
-	marshalUtil.WriteBytes(payload.branchPayloadId[:])
-	marshalUtil.WriteBytes(transferId[:])
-	var id PayloadId = blake2b.Sum256(marshalUtil.Bytes())
-	payload.id = &id
-
-	return id
-}
-
-func (payload *Payload) GetTrunkPayloadId() PayloadId {
-	return payload.trunkPayloadId
-}
-
-func (payload *Payload) GetBranchPayloadId() PayloadId {
-	return payload.branchPayloadId
-}
-
-func (payload *Payload) GetTransfer() *Transfer {
-	return payload.transfer
-}
-
-// region Payload implementation ///////////////////////////////////////////////////////////////////////////////////////
-
-var Type = payload.Type(1)
-
-func (payload *Payload) GetType() payload.Type {
-	return Type
-}
-
-func (payload *Payload) MarshalBinary() (bytes []byte, err error) {
-	// acquire lock for reading bytes
-	payload.bytesMutex.RLock()
-
-	// return if bytes have been determined already
-	if bytes = payload.bytes; bytes != nil {
-		defer payload.bytesMutex.RUnlock()
-
-		return
-	}
-
-	// switch to write lock
-	payload.bytesMutex.RUnlock()
-	payload.bytesMutex.Lock()
-	defer payload.bytesMutex.Unlock()
-
-	// return if bytes have been determined in the mean time
-	if bytes = payload.bytes; bytes != nil {
-		return
-	}
-
-	// retrieve bytes of transfer
-	transferBytes, err := payload.GetTransfer().MarshalBinary()
-	if err != nil {
-		return
-	}
-
-	// marshal fields
-	marshalUtil := marshalutil.New(PayloadIdLength + PayloadIdLength + TransferIdLength)
-	marshalUtil.WriteBytes(payload.trunkPayloadId[:])
-	marshalUtil.WriteBytes(payload.branchPayloadId[:])
-	marshalUtil.WriteBytes(transferBytes)
-	bytes = marshalUtil.Bytes()
-
-	// store result
-	payload.bytes = bytes
-
-	return
-}
-
-func (payload *Payload) UnmarshalBinary(data []byte) (err error) {
-	marshalUtil := marshalutil.New(data)
-
-	trunkTransactionIdBytes, err := marshalUtil.ReadBytes(PayloadIdLength)
-	if err != nil {
-		return
-	}
-
-	branchTransactionIdBytes, err := marshalUtil.ReadBytes(PayloadIdLength)
-	if err != nil {
-		return
-	}
-
-	valueTransfer := &Transfer{}
-	if err = valueTransfer.UnmarshalBinary(marshalUtil.ReadRemainingBytes()); err != nil {
-		return
-	}
-
-	payload.trunkPayloadId = NewPayloadId(trunkTransactionIdBytes)
-	payload.branchPayloadId = NewPayloadId(branchTransactionIdBytes)
-	payload.transfer = valueTransfer
-	payload.bytes = data
-
-	return
-}
-
-func init() {
-	payload.RegisterType(Type, func(data []byte) (payload payload.Payload, err error) {
-		payload = &Payload{}
-		err = payload.UnmarshalBinary(data)
-
-		return
-	})
-}
-
-// define contract (ensure that the struct fulfills the corresponding interface)
-var _ payload.Payload = &Payload{}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// region StorableObject implementation ////////////////////////////////////////////////////////////////////////////////
-
-// MarshalBinary() (bytes []byte, err error) already implemented by Payload
-
-// UnmarshalBinary(data []byte) (err error) already implemented by Payload
-
-func (payload *Payload) GetStorageKey() []byte {
-	id := payload.GetId()
-
-	return id[:]
-}
-
-func (payload *Payload) Update(other objectstorage.StorableObject) {
-	panic("a Payload should never be updated")
-}
-
-// define contract (ensure that the struct fulfills the corresponding interface)
-var _ objectstorage.StorableObject = &Payload{}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/packages/binary/valuetransfers/payload/payload.go b/packages/binary/valuetransfers/payload/payload.go
index 7ffe6aa80aba954d494e9421fd2a6efd91ee0c4b..39430b2179a54e991c57a15d19883c112ff7f153 100644
--- a/packages/binary/valuetransfers/payload/payload.go
+++ b/packages/binary/valuetransfers/payload/payload.go
@@ -36,6 +36,8 @@ func New(trunkPayloadId, branchPayloadId payloadid.Id, valueTransfer *transfer.T
 	}
 }
 
+// FromBytes parses the marshaled version of a Payload into an object.
+// It either returns a new Payload or fills an optionally provided Payload with the parsed information.
 func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, err error, consumedBytes int) {
 	// determine the target object that will hold the unmarshaled information
 	switch len(optionalTargetObject) {
diff --git a/packages/binary/valuetransfers/payload/transfer/inputs/inputs.go b/packages/binary/valuetransfers/payload/transfer/inputs/inputs.go
index dd86096b4b397c071219667255560d8dede40bc8..d36935b03eb1a87859a4733605b841b488c88dce 100644
--- a/packages/binary/valuetransfers/payload/transfer/inputs/inputs.go
+++ b/packages/binary/valuetransfers/payload/transfer/inputs/inputs.go
@@ -3,10 +3,10 @@ package inputs
 import (
 	"github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap"
 	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
-	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/address"
+	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/address"
 	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/id"
 	transferid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/id"
-	transferoutputid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/output/id"
+	transferoutputid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/transferoutput/id"
 )
 
 type Inputs struct {
diff --git a/packages/binary/valuetransfers/payload/transfer/outputs/outputs.go b/packages/binary/valuetransfers/payload/transfer/outputs/outputs.go
index f89c40ec1c84d4e2c9d9e5cb9a364358ea860b7d..4c66d7ef0a0d2dceeb3d61000691b5bde1d9cb49 100644
--- a/packages/binary/valuetransfers/payload/transfer/outputs/outputs.go
+++ b/packages/binary/valuetransfers/payload/transfer/outputs/outputs.go
@@ -3,8 +3,8 @@ package outputs
 import (
 	"github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap"
 	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
-	address2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/address"
-	coloredbalance2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/coloredbalance"
+	address2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/address"
+	coloredbalance2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/coloredbalance"
 )
 
 type Outputs struct {
diff --git a/packages/binary/valuetransfers/payload/transfer/signatures/signatures.go b/packages/binary/valuetransfers/payload/transfer/signatures/signatures.go
new file mode 100644
index 0000000000000000000000000000000000000000..87f18aacd027ce65b3eafd1b9e772e489e324e93
--- /dev/null
+++ b/packages/binary/valuetransfers/payload/transfer/signatures/signatures.go
@@ -0,0 +1,4 @@
+package signatures
+
+type Signatures struct {
+}
diff --git a/packages/binary/valuetransfers/payload/transfer/transfer.go b/packages/binary/valuetransfers/payload/transfer/transfer.go
index af9357069a881b95434914e8acd395f4ce81b8e8..ab9f3bfafc6002412e26c95729c49a8cf970b398 100644
--- a/packages/binary/valuetransfers/payload/transfer/transfer.go
+++ b/packages/binary/valuetransfers/payload/transfer/transfer.go
@@ -10,9 +10,11 @@ import (
 	"golang.org/x/crypto/blake2b"
 
 	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
+	"github.com/iotaledger/goshimmer/packages/binary/signature/ed25119"
 	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/id"
 	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/inputs"
 	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/outputs"
+	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/signatures"
 )
 
 // region IMPLEMENT Transfer ///////////////////////////////////////////////////////////////////////////////////////////
@@ -20,12 +22,20 @@ import (
 type Transfer struct {
 	objectstorage.StorableObjectFlags
 
+	inputs     *inputs.Inputs
+	outputs    *outputs.Outputs
+	signatures *signatures.Signatures
+
 	id      *id.Id
-	inputs  *inputs.Inputs
-	outputs *outputs.Outputs
-	bytes   []byte
+	idMutex sync.RWMutex
+
+	essenceBytes      []byte
+	essenceBytesMutex sync.RWMutex
+
+	signatureBytes      []byte
+	signatureBytesMutex sync.RWMutex
 
-	idMutex    sync.RWMutex
+	bytes      []byte
 	bytesMutex sync.RWMutex
 }
 
@@ -73,7 +83,7 @@ func FromBytes(bytes []byte, optionalTargetObject ...*Transfer) (result *Transfe
 	return
 }
 
-func TransferFromStorage(key []byte) *Transfer {
+func FromStorage(key []byte) *Transfer {
 	id := id.New(key)
 
 	return &Transfer{
@@ -148,6 +158,10 @@ func (transfer *Transfer) Bytes() []byte {
 	return transfer.bytes
 }
 
+func (transfer *Transfer) Sign(pair ed25119.KeyPair) {
+	//transfer.signatures[pair.PublicKey] = pair.PrivateKey.Sign(transfer.Bytes())
+}
+
 func (transfer *Transfer) String() string {
 	id := transfer.GetId()
 
diff --git a/packages/binary/valuetransfers/payload_id.go b/packages/binary/valuetransfers/payload_id.go
deleted file mode 100644
index c596cfb0a794c0857abe340005b3015ccc7cf3f8..0000000000000000000000000000000000000000
--- a/packages/binary/valuetransfers/payload_id.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package valuetransfers
-
-import (
-	"github.com/mr-tron/base58"
-)
-
-type PayloadId [PayloadIdLength]byte
-
-func NewPayloadId(idBytes []byte) (result PayloadId) {
-	copy(result[:], idBytes)
-
-	return
-}
-
-func (id PayloadId) String() string {
-	return base58.Encode(id[:])
-}
-
-var EmptyPayloadId PayloadId
-
-const PayloadIdLength = 32
diff --git a/packages/binary/valuetransfers/test/payload_test.go b/packages/binary/valuetransfers/test/payload_test.go
index e7b023f666b63e6b37b440d6313fd4ae2d715b7d..ae7cc819511c3d4d7a9ea140afdca86508d679ae 100644
--- a/packages/binary/valuetransfers/test/payload_test.go
+++ b/packages/binary/valuetransfers/test/payload_test.go
@@ -4,20 +4,70 @@ import (
 	"fmt"
 	"testing"
 
-	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload"
+	"github.com/iotaledger/goshimmer/packages/binary/identity"
+	"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction"
+	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/address"
+	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/coloredbalance"
+	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/coloredbalance/color"
+	valuepayload "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload"
 	payloadid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/id"
 	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer"
-	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/address"
-	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/coloredbalance"
-	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/coloredbalance/color"
 	transferid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/id"
 	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/inputs"
-	transferoutputid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/output/id"
 	"github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/outputs"
+	transferoutputid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/transferoutput/id"
 )
 
+func ExamplePayload() {
+	// 1. create value transfer (user provides this)
+	valueTransfer := transfer.New(
+		// inputs
+		inputs.New(
+			transferoutputid.New(address.New([]byte("input_address1")), transferid.New([]byte("transfer1"))),
+			transferoutputid.New(address.New([]byte("input_address2")), transferid.New([]byte("transfer2"))),
+		),
+
+		// outputs
+		outputs.New(map[address.Address][]*coloredbalance.ColoredBalance{
+			address.New([]byte("output_address")): {
+				coloredbalance.New(color.IOTA, 1337),
+			},
+		}),
+	)
+
+	// 2. create value payload (the ontology creates this and wraps the user provided transfer accordingly)
+	valuePayload := valuepayload.New(
+		// trunk in "value transfer ontology" (filled by ontology tipSelector)
+		payloadid.Empty,
+
+		// branch in "value transfer ontology"  (filled by ontology tipSelector)
+		payloadid.Empty,
+
+		// value transfer
+		valueTransfer,
+	)
+
+	// 3. build actual transaction (the base layer creates this and wraps the ontology provided payload)
+	tx := transaction.New(
+		// trunk in "network tangle" ontology (filled by tipSelector)
+		transaction.EmptyId,
+
+		// branch in "network tangle" ontology (filled by tipSelector)
+		transaction.EmptyId,
+
+		// issuer of the transaction (signs automatically)
+		identity.Generate(),
+
+		// payload
+		valuePayload,
+	)
+
+	fmt.Println(tx)
+}
+
 func TestPayload(t *testing.T) {
-	originalPayload := payload.New(
+
+	originalPayload := valuepayload.New(
 		payloadid.Empty,
 		payloadid.Empty,
 		transfer.New(
@@ -28,13 +78,13 @@ func TestPayload(t *testing.T) {
 
 			outputs.New(map[address.Address][]*coloredbalance.ColoredBalance{
 				address.New([]byte("output_address")): {
-					coloredbalance.New(color.COLOR_IOTA, 1337),
+					coloredbalance.New(color.IOTA, 1337),
 				},
 			}),
 		),
 	)
 
-	clonedPayload, err, _ := payload.FromBytes(originalPayload.Bytes())
+	clonedPayload, err, _ := valuepayload.FromBytes(originalPayload.Bytes())
 	if err != nil {
 		panic(err)
 	}
diff --git a/packages/binary/valuetransfers/transfer.go b/packages/binary/valuetransfers/transfer.go
deleted file mode 100644
index 6cd4df8cd471c33a6101b6f27b5e991ce4e56bcf..0000000000000000000000000000000000000000
--- a/packages/binary/valuetransfers/transfer.go
+++ /dev/null
@@ -1,190 +0,0 @@
-package valuetransfers
-
-import (
-	"fmt"
-	"sync"
-
-	"github.com/iotaledger/hive.go/objectstorage"
-	"github.com/iotaledger/hive.go/stringify"
-	"github.com/mr-tron/base58"
-	"golang.org/x/crypto/blake2b"
-
-	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
-)
-
-// region IMPLEMENT Transfer ///////////////////////////////////////////////////////////////////////////////////////////
-
-type Transfer struct {
-	objectstorage.StorableObjectFlags
-
-	id      *TransferId
-	inputs  *TransferInputs
-	outputs *Outputs
-	bytes   []byte
-
-	idMutex    sync.RWMutex
-	bytesMutex sync.RWMutex
-}
-
-func NewTransfer(inputs *TransferInputs, outputs *Outputs) *Transfer {
-	return &Transfer{
-		inputs:  inputs,
-		outputs: outputs,
-	}
-}
-
-func TransferFromBytes(bytes []byte, optionalTargetObject ...*Transfer) (result *Transfer, err error, consumedBytes int) {
-	// determine the target object that will hold the unmarshaled information
-	switch len(optionalTargetObject) {
-	case 0:
-		result = &Transfer{}
-	case 1:
-		result = optionalTargetObject[0]
-	default:
-		panic("too many arguments in call to OutputFromBytes")
-	}
-
-	// initialize helper
-	marshalUtil := marshalutil.New(bytes)
-
-	// unmarshal inputs
-	if parseResult, inputsErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return TransferInputsFromBytes(data) }); inputsErr != nil {
-		err = inputsErr
-
-		return
-	} else {
-		result.inputs = parseResult.(*TransferInputs)
-	}
-
-	// unmarshal outputs
-	if parseResult, outputsErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return OutputsFromBytes(data) }); outputsErr != nil {
-		err = outputsErr
-
-		return
-	} else {
-		result.outputs = parseResult.(*Outputs)
-	}
-
-	// return the number of bytes we processed
-	consumedBytes = marshalUtil.ReadOffset()
-
-	// store bytes, so we don't have to marshal manually
-	result.bytes = bytes[:consumedBytes]
-
-	return
-}
-
-func TransferFromStorage(key []byte) *Transfer {
-	id := NewTransferId(key)
-
-	return &Transfer{
-		id: &id,
-	}
-}
-
-func (transfer *Transfer) GetId() TransferId {
-	// acquire lock for reading id
-	transfer.idMutex.RLock()
-
-	// return if id has been calculated already
-	if transfer.id != nil {
-		defer transfer.idMutex.RUnlock()
-
-		return *transfer.id
-	}
-
-	// switch to write lock
-	transfer.idMutex.RUnlock()
-	transfer.idMutex.Lock()
-	defer transfer.idMutex.Unlock()
-
-	// return if id has been calculated in the mean time
-	if transfer.id != nil {
-		return *transfer.id
-	}
-
-	// otherwise calculate the id
-	idBytes := blake2b.Sum256(transfer.Bytes())
-	transferId := NewTransferId(idBytes[:])
-
-	// cache result for later calls
-	transfer.id = &transferId
-
-	return transferId
-}
-
-func (transfer *Transfer) Bytes() []byte {
-	// acquired read lock on bytes
-	transfer.bytesMutex.RLock()
-
-	// return bytes if the object has been marshaled already
-	if transfer.bytes != nil {
-		defer transfer.bytesMutex.RUnlock()
-
-		return transfer.bytes
-	}
-
-	// switch to write lock
-	transfer.bytesMutex.RUnlock()
-	transfer.bytesMutex.Lock()
-	defer transfer.bytesMutex.Unlock()
-
-	// return bytes if the object has been marshaled in the mean time
-	if bytes := transfer.bytes; bytes != nil {
-		return bytes
-	}
-
-	// create marshal helper
-	marshalUtil := marshalutil.New()
-
-	// marshal inputs
-	marshalUtil.WriteBytes(transfer.inputs.ToBytes())
-
-	// marshal outputs
-	marshalUtil.WriteBytes(transfer.outputs.Bytes())
-
-	// store marshaled result
-	transfer.bytes = marshalUtil.Bytes()
-
-	return transfer.bytes
-}
-
-func (transfer *Transfer) String() string {
-	id := transfer.GetId()
-
-	return stringify.Struct("Transfer"+fmt.Sprintf("(%p)", transfer),
-		stringify.StructField("id", base58.Encode(id[:])),
-		stringify.StructField("inputs", transfer.inputs),
-		stringify.StructField("outputs", transfer.outputs),
-	)
-}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// region IMPLEMENT StorableObject interface ///////////////////////////////////////////////////////////////////////////
-
-// define contract (ensure that the struct fulfills the given interface)
-var _ objectstorage.StorableObject = &Transfer{}
-
-func (transfer *Transfer) GetStorageKey() []byte {
-	id := transfer.GetId()
-
-	return id[:]
-}
-
-func (transfer *Transfer) Update(other objectstorage.StorableObject) {
-	panic("update forbidden")
-}
-
-// MarshalBinary returns a bytes representation of the transfer by implementing the encoding.BinaryMarshaler interface.
-func (transfer *Transfer) MarshalBinary() ([]byte, error) {
-	return transfer.Bytes(), nil
-}
-
-func (transfer *Transfer) UnmarshalBinary(bytes []byte) (err error) {
-	_, err, _ = TransferFromBytes(bytes, transfer)
-
-	return
-}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/packages/binary/valuetransfers/transfer_id.go b/packages/binary/valuetransfers/transfer_id.go
deleted file mode 100644
index ed2c198b418a4041c5abb81f39ea9674366e7a48..0000000000000000000000000000000000000000
--- a/packages/binary/valuetransfers/transfer_id.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package valuetransfers
-
-import (
-	"github.com/mr-tron/base58"
-)
-
-type TransferId [TransferIdLength]byte
-
-func NewTransferId(idBytes []byte) (result TransferId) {
-	copy(result[:], idBytes)
-
-	return
-}
-
-func (id TransferId) String() string {
-	return base58.Encode(id[:])
-}
-
-const TransferIdLength = 32
diff --git a/packages/binary/valuetransfers/transfer_inputs.go b/packages/binary/valuetransfers/transfer_inputs.go
deleted file mode 100644
index aaffde448d5dcc3dcb5895000c18d064b90ac6ff..0000000000000000000000000000000000000000
--- a/packages/binary/valuetransfers/transfer_inputs.go
+++ /dev/null
@@ -1,132 +0,0 @@
-package valuetransfers
-
-import (
-	"github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap"
-	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
-)
-
-type TransferInputs struct {
-	*orderedmap.OrderedMap
-}
-
-func NewTransferInputs(transferOutputIds ...TransferOutputId) (inputs *TransferInputs) {
-	inputs = &TransferInputs{orderedmap.New()}
-	for _, transferOutputId := range transferOutputIds {
-		inputs.Add(transferOutputId)
-	}
-
-	return
-}
-
-func TransferInputsFromBytes(bytes []byte) (inputs *TransferInputs, err error, consumedBytes int) {
-	inputs = NewTransferInputs()
-
-	marshalUtil := marshalutil.New(bytes)
-	inputCount, err := marshalUtil.ReadUint32()
-	if err != nil {
-		return
-	}
-
-	for i := uint32(0); i < inputCount; i++ {
-		addressBytes, readErr := marshalUtil.ReadBytes(AddressLength)
-		if readErr != nil {
-			err = readErr
-
-			return
-		}
-		address := NewAddress(addressBytes)
-
-		transferIdBytes, readErr := marshalUtil.ReadBytes(TransferIdLength)
-		if readErr != nil {
-			err = readErr
-
-			return
-		}
-		transferId := NewTransferId(transferIdBytes)
-
-		addressMap, addressExists := inputs.Get(address)
-		if !addressExists {
-			addressMap = orderedmap.New()
-
-			inputs.Set(address, addressMap)
-		}
-		addressMap.(*orderedmap.OrderedMap).Set(transferId, NewTransferOutputId(address, transferId))
-	}
-
-	consumedBytes = marshalUtil.ReadOffset()
-
-	return
-}
-
-func (inputs *TransferInputs) Add(input TransferOutputId) *TransferInputs {
-	address := input.GetAddress()
-	transferId := input.GetTransferId()
-
-	addressMap, addressExists := inputs.Get(address)
-	if !addressExists {
-		addressMap = orderedmap.New()
-
-		inputs.Set(address, addressMap)
-	}
-
-	addressMap.(*orderedmap.OrderedMap).Set(transferId, input)
-
-	return inputs
-}
-
-func (inputs *TransferInputs) ToBytes() (bytes []byte) {
-	marshalUtil := marshalutil.New()
-
-	marshalUtil.WriteSeek(4)
-	var inputCounter uint32
-	inputs.ForEach(func(transferOutputId TransferOutputId) {
-		marshalUtil.WriteBytes(transferOutputId.ToBytes())
-
-		inputCounter++
-	})
-	marshalUtil.WriteSeek(0)
-	marshalUtil.WriteUint32(inputCounter)
-
-	return marshalUtil.Bytes()
-}
-
-func (inputs *TransferInputs) ForEach(consumer func(transferOutputId TransferOutputId)) {
-	inputs.OrderedMap.ForEach(func(key, value interface{}) bool {
-		value.(*orderedmap.OrderedMap).ForEach(func(key, value interface{}) bool {
-			consumer(value.(TransferOutputId))
-
-			return true
-		})
-
-		return true
-	})
-}
-
-func (inputs *TransferInputs) ForEachAddress(consumer func(address Address)) {
-	inputs.OrderedMap.ForEach(func(key, value interface{}) bool {
-		consumer(key.(Address))
-
-		return true
-	})
-}
-
-func (inputs *TransferInputs) String() string {
-	if inputs == nil {
-		return "<nil>"
-	}
-
-	result := "[\n"
-
-	empty := true
-	inputs.ForEach(func(transferOutputId TransferOutputId) {
-		empty = false
-
-		result += "    " + transferOutputId.String() + ",\n"
-	})
-
-	if empty {
-		result += "    <empty>\n"
-	}
-
-	return result + "]"
-}
diff --git a/packages/binary/valuetransfers/payload/transfer/output/id/id.go b/packages/binary/valuetransfers/transferoutput/id/id.go
similarity index 96%
rename from packages/binary/valuetransfers/payload/transfer/output/id/id.go
rename to packages/binary/valuetransfers/transferoutput/id/id.go
index 159dd3d9d7ee0913bbbd8661ce2338e98072cab8..0d2c7e95c96aecb91d501886442760366d31ce69 100644
--- a/packages/binary/valuetransfers/payload/transfer/output/id/id.go
+++ b/packages/binary/valuetransfers/transferoutput/id/id.go
@@ -3,7 +3,7 @@ package id
 import (
 	"github.com/mr-tron/base58"
 
-	address2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/address"
+	address2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/address"
 	id2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/id"
 )
 
diff --git a/packages/binary/valuetransfers/transferoutput_id.go b/packages/binary/valuetransfers/transferoutput_id.go
deleted file mode 100644
index cbb9c76d619888179404ac28e82a5e2ce592d635..0000000000000000000000000000000000000000
--- a/packages/binary/valuetransfers/transferoutput_id.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package valuetransfers
-
-import (
-	"github.com/mr-tron/base58"
-)
-
-type TransferOutputId [TransferOutputIdLength]byte
-
-func NewTransferOutputId(address Address, transferId TransferId) (transferOutputId TransferOutputId) {
-	copy(transferOutputId[:AddressLength], address.ToBytes())
-	copy(transferOutputId[AddressLength:], transferId[:])
-
-	return
-}
-
-func TransferOutputIdFromBytes(bytes []byte) (transferOutputId TransferOutputId) {
-	copy(transferOutputId[:], bytes)
-
-	return
-}
-
-func (transferOutputId TransferOutputId) GetAddress() Address {
-	return NewAddress(transferOutputId[:AddressLength])
-}
-
-func (transferOutputId TransferOutputId) GetTransferId() TransferId {
-	return NewTransferId(transferOutputId[AddressLength:])
-}
-
-func (transferOutputId TransferOutputId) ToBytes() []byte {
-	return transferOutputId[:]
-}
-
-func (transferOutputId TransferOutputId) String() string {
-	return "TransferOutputId(" + base58.Encode(transferOutputId[:]) + ")"
-}
-
-const TransferOutputIdLength = AddressLength + TransferIdLength