diff --git a/packages/model/meta_transaction/constants.go b/packages/model/meta_transaction/constants.go
index 1e5cbdcccfb0e7508fc429cbb41744b7037a0c17..814e958c82ca4e359b1553650fedc71a25d0561f 100644
--- a/packages/model/meta_transaction/constants.go
+++ b/packages/model/meta_transaction/constants.go
@@ -1,6 +1,7 @@
 package meta_transaction
 
 import (
+	"github.com/iotaledger/iota.go/consts"
 	"github.com/iotaledger/iota.go/trinary"
 )
 
@@ -12,6 +13,7 @@ const (
 	TAIL_OFFSET                    = HEAD_END
 	TRANSACTION_TYPE_OFFSET        = TAIL_END
 	DATA_OFFSET                    = TRANSACTION_TYPE_END
+	NONCE_OFFSET                   = DATA_END
 
 	SHARD_MARKER_SIZE            = 11
 	TRUNK_TRANSACTION_HASH_SIZE  = 243
@@ -20,6 +22,7 @@ const (
 	TAIL_SIZE                    = 1
 	TRANSACTION_TYPE_SIZE        = 8
 	DATA_SIZE                    = 6993
+	NONCE_SIZE                   = consts.NonceTrinarySize
 
 	SHARD_MARKER_END            = SHARD_MARKER_OFFSET + SHARD_MARKER_SIZE
 	TRUNK_TRANSACTION_HASH_END  = TRUNK_TRANSACTION_HASH_OFFSET + TRUNK_TRANSACTION_HASH_SIZE
@@ -28,8 +31,9 @@ const (
 	TAIL_END                    = TAIL_OFFSET + TAIL_SIZE
 	TRANSACTION_TYPE_END        = TRANSACTION_TYPE_OFFSET + TRANSACTION_TYPE_SIZE
 	DATA_END                    = DATA_OFFSET + DATA_SIZE
+	NONCE_END                   = NONCE_OFFSET + NONCE_SIZE
 
-	MARSHALED_TOTAL_SIZE = DATA_END
+	MARSHALED_TOTAL_SIZE = NONCE_END
 
 	BRANCH_NULL_HASH = trinary.Trytes("999999999999999999999999999999999999999999999999999999999999999999999999999999999")
 )
diff --git a/packages/model/meta_transaction/meta_transaction.go b/packages/model/meta_transaction/meta_transaction.go
index 575ea6b435bc775e00cc253fa362ce8f3ee95153..c20bab96a35c761f6ee85bb17b8b679113df08dd 100644
--- a/packages/model/meta_transaction/meta_transaction.go
+++ b/packages/model/meta_transaction/meta_transaction.go
@@ -3,8 +3,11 @@ package meta_transaction
 import (
 	"sync"
 
-	"github.com/iotaledger/goshimmer/packages/curl"
+	"github.com/iotaledger/iota.go/consts"
+	"github.com/iotaledger/iota.go/curl"
+	"github.com/iotaledger/iota.go/pow"
 	"github.com/iotaledger/iota.go/trinary"
+	"github.com/pkg/errors"
 )
 
 type MetaTransaction struct {
@@ -19,6 +22,7 @@ type MetaTransaction struct {
 	transactionType       *trinary.Trytes
 	data                  trinary.Trits
 	modified              bool
+	nonce                 *trinary.Trytes
 
 	hasherMutex                sync.RWMutex
 	hashMutex                  sync.RWMutex
@@ -31,6 +35,7 @@ type MetaTransaction struct {
 	dataMutex                  sync.RWMutex
 	bytesMutex                 sync.RWMutex
 	modifiedMutex              sync.RWMutex
+	nonceMutex                 sync.RWMutex
 
 	trits trinary.Trits
 	bytes []byte
@@ -85,7 +90,7 @@ func (this *MetaTransaction) GetHash() (result trinary.Trytes) {
 		defer this.hashMutex.Unlock()
 		if this.hash == nil {
 			this.hasherMutex.Lock()
-			this.parseHashRelatedDetails()
+			this.computeHashDetails()
 			this.hasherMutex.Unlock()
 		}
 	} else {
@@ -106,7 +111,7 @@ func (this *MetaTransaction) GetWeightMagnitude() (result int) {
 		defer this.hashMutex.Unlock()
 		if this.hash == nil {
 			this.hasherMutex.Lock()
-			this.parseHashRelatedDetails()
+			this.computeHashDetails()
 			this.hasherMutex.Unlock()
 		}
 	} else {
@@ -118,9 +123,26 @@ func (this *MetaTransaction) GetWeightMagnitude() (result int) {
 	return
 }
 
+// returns the trytes that are relevant for the transaction hash
+func (this *MetaTransaction) getHashEssence() trinary.Trits {
+	txTrits := this.trits
+
+	// very dirty hack, to get an iota.go compatible size
+	if len(txTrits) > consts.TransactionTrinarySize {
+		panic("transaction too large")
+	}
+	essenceTrits := make([]int8, consts.TransactionTrinarySize)
+	copy(essenceTrits[consts.TransactionTrinarySize-len(txTrits):], txTrits)
+
+	return essenceTrits
+}
+
 // hashes the transaction using curl (without locking - internal usage)
-func (this *MetaTransaction) parseHashRelatedDetails() {
-	hashTrits := curl.CURLP81.Hash(this.trits)
+func (this *MetaTransaction) computeHashDetails() {
+	hashTrits, err := curl.HashTrits(this.getHashEssence())
+	if err != nil {
+		panic(err)
+	}
 	hashTrytes := trinary.MustTritsToTrytes(hashTrits)
 
 	this.hash = &hashTrytes
@@ -466,6 +488,49 @@ func (this *MetaTransaction) GetBytes() (result []byte) {
 	return
 }
 
+func (this *MetaTransaction) GetNonce() trinary.Trytes {
+	this.nonceMutex.RLock()
+	if this.nonce == nil {
+		this.nonceMutex.RUnlock()
+		this.nonceMutex.Lock()
+		defer this.nonceMutex.Unlock()
+		if this.nonce == nil {
+			nonce := trinary.MustTritsToTrytes(this.trits[NONCE_OFFSET:NONCE_END])
+
+			this.nonce = &nonce
+		}
+	} else {
+		defer this.nonceMutex.RUnlock()
+	}
+
+	return *this.nonce
+}
+
+func (this *MetaTransaction) SetNonce(nonce trinary.Trytes) bool {
+	this.nonceMutex.RLock()
+	if this.nonce == nil || *this.nonce != nonce {
+		this.nonceMutex.RUnlock()
+		this.nonceMutex.Lock()
+		defer this.nonceMutex.Unlock()
+		if this.nonce == nil || *this.nonce != nonce {
+			this.nonce = &nonce
+
+			this.hasherMutex.RLock()
+			copy(this.trits[NONCE_OFFSET:NONCE_END], trinary.MustTrytesToTrits(nonce)[:NONCE_SIZE])
+			this.hasherMutex.RUnlock()
+
+			this.SetModified(true)
+			this.ReHash()
+
+			return true
+		}
+	} else {
+		this.nonceMutex.RUnlock()
+	}
+
+	return false
+}
+
 // returns true if the transaction contains unsaved changes (supports concurrency)
 func (this *MetaTransaction) GetModified() bool {
 	this.modifiedMutex.RLock()
@@ -481,3 +546,18 @@ func (this *MetaTransaction) SetModified(modified bool) {
 
 	this.modified = modified
 }
+
+func (this *MetaTransaction) DoProofOfWork(mwm int) error {
+	this.hasherMutex.Lock()
+	powTrytes := trinary.MustTritsToTrytes(this.getHashEssence())
+	_, pow := pow.GetFastestProofOfWorkImpl()
+	nonce, err := pow(powTrytes, mwm)
+	this.hasherMutex.Unlock()
+
+	if err != nil {
+		return errors.Wrap(err, "PoW failed")
+	}
+	this.SetNonce(nonce)
+
+	return nil
+}
diff --git a/packages/model/meta_transaction/meta_transaction_test.go b/packages/model/meta_transaction/meta_transaction_test.go
index 2ba055b76a74928485bfd0b11a9d959d68bd47ac..fa6ec565255b903bd4e917b631873c54696230ba 100644
--- a/packages/model/meta_transaction/meta_transaction_test.go
+++ b/packages/model/meta_transaction/meta_transaction_test.go
@@ -1,40 +1,55 @@
 package meta_transaction
 
 import (
-	"fmt"
 	"sync"
 	"testing"
 
 	"github.com/iotaledger/iota.go/trinary"
-	"github.com/magiconair/properties/assert"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
+const (
+	shardMarker           = trinary.Trytes("NPHTQORL9XKA")
+	trunkTransactionHash  = trinary.Trytes("99999999999999999999999999999999999999999999999999999999999999999999999999999999A")
+	branchTransactionHash = trinary.Trytes("99999999999999999999999999999999999999999999999999999999999999999999999999999999B")
+	head                  = true
+	tail                  = true
+	transactionType       = trinary.Trytes("9999999999999999999999")
+)
+
+func newTestTransaction() *MetaTransaction {
+	tx := New()
+	tx.SetShardMarker(shardMarker)
+	tx.SetTrunkTransactionHash(trunkTransactionHash)
+	tx.SetBranchTransactionHash(branchTransactionHash)
+	tx.SetHead(head)
+	tx.SetTail(tail)
+	tx.SetTransactionType(transactionType)
+
+	return tx
+}
+
+func TestDoPow(t *testing.T) {
+	tx := newTestTransaction()
+	require.NoError(t, tx.DoProofOfWork(10))
+
+	assert.GreaterOrEqual(t, tx.GetWeightMagnitude(), 10)
+}
+
 func TestMetaTransaction_SettersGetters(t *testing.T) {
-	shardMarker := trinary.Trytes("NPHTQORL9XKA")
-	trunkTransactionHash := trinary.Trytes("99999999999999999999999999999999999999999999999999999999999999999999999999999999A")
-	branchTransactionHash := trinary.Trytes("99999999999999999999999999999999999999999999999999999999999999999999999999999999B")
-	head := true
-	tail := true
-	transactionType := trinary.Trytes("9999999999999999999999")
-
-	transaction := New()
-	transaction.SetShardMarker(shardMarker)
-	transaction.SetTrunkTransactionHash(trunkTransactionHash)
-	transaction.SetBranchTransactionHash(branchTransactionHash)
-	transaction.SetHead(head)
-	transaction.SetTail(tail)
-	transaction.SetTransactionType(transactionType)
-
-	assert.Equal(t, transaction.GetWeightMagnitude(), 0)
-	assert.Equal(t, transaction.GetShardMarker(), shardMarker)
-	assert.Equal(t, transaction.GetTrunkTransactionHash(), trunkTransactionHash)
-	assert.Equal(t, transaction.GetBranchTransactionHash(), branchTransactionHash)
-	assert.Equal(t, transaction.IsHead(), head)
-	assert.Equal(t, transaction.IsTail(), tail)
-	assert.Equal(t, transaction.GetTransactionType(), transactionType)
-	assert.Equal(t, transaction.GetHash(), FromBytes(transaction.GetBytes()).GetHash())
-
-	fmt.Println(transaction.GetHash())
+	tx := newTestTransaction()
+
+	assert.Equal(t, tx.GetWeightMagnitude(), 0)
+	assert.Equal(t, tx.GetShardMarker(), shardMarker)
+	assert.Equal(t, tx.GetTrunkTransactionHash(), trunkTransactionHash)
+	assert.Equal(t, tx.GetBranchTransactionHash(), branchTransactionHash)
+	assert.Equal(t, tx.IsHead(), head)
+	assert.Equal(t, tx.IsTail(), tail)
+	assert.Equal(t, tx.GetTransactionType(), transactionType)
+	assert.Equal(t, tx.GetHash(), FromBytes(tx.GetBytes()).GetHash())
+
+	assert.EqualValues(t, "KKDVHBENVLQUNO9WOWWEJPBBHUSYRSRKIMZWCFCDB9RYZKYWLAYWRIBRQETBFKE9TIVWQPCKFWAMCLCAV", tx.GetHash())
 }
 
 func BenchmarkMetaTransaction_GetHash(b *testing.B) {
diff --git a/packages/model/value_transaction/constants.go b/packages/model/value_transaction/constants.go
index cc2175fd49fa7f98581dc7321a6aca7c325adc5f..c602d1ea6d3870cbc17160914f63c6af1f234eca 100644
--- a/packages/model/value_transaction/constants.go
+++ b/packages/model/value_transaction/constants.go
@@ -10,20 +10,17 @@ const (
 	ADDRESS_OFFSET                    = 0
 	VALUE_OFFSET                      = ADDRESS_END
 	TIMESTAMP_OFFSET                  = VALUE_END
-	NONCE_OFFSET                      = TIMESTAMP_END
-	SIGNATURE_MESSAGE_FRAGMENT_OFFSET = NONCE_END
+	SIGNATURE_MESSAGE_FRAGMENT_OFFSET = TIMESTAMP_SIZE
 
 	ADDRESS_SIZE                    = 243
 	VALUE_SIZE                      = 81
 	TIMESTAMP_SIZE                  = 27
-	NONCE_SIZE                      = 81
 	SIGNATURE_MESSAGE_FRAGMENT_SIZE = 6561
 	BUNDLE_ESSENCE_SIZE             = ADDRESS_SIZE + VALUE_SIZE + SIGNATURE_MESSAGE_FRAGMENT_SIZE
 
 	ADDRESS_END                    = ADDRESS_OFFSET + ADDRESS_SIZE
 	VALUE_END                      = VALUE_OFFSET + VALUE_SIZE
 	TIMESTAMP_END                  = TIMESTAMP_OFFSET + TIMESTAMP_SIZE
-	NONCE_END                      = NONCE_OFFSET + NONCE_SIZE
 	SIGNATURE_MESSAGE_FRAGMENT_END = SIGNATURE_MESSAGE_FRAGMENT_OFFSET + SIGNATURE_MESSAGE_FRAGMENT_SIZE
 
 	TOTAL_SIZE = SIGNATURE_MESSAGE_FRAGMENT_END
diff --git a/packages/model/value_transaction/value_transaction.go b/packages/model/value_transaction/value_transaction.go
index e4972d271af93578c7d43fb147fddabcdf915ba5..b42a647348d7b28ec86b8a8ed79ac2506b8863b4 100644
--- a/packages/model/value_transaction/value_transaction.go
+++ b/packages/model/value_transaction/value_transaction.go
@@ -16,8 +16,6 @@ type ValueTransaction struct {
 	valueMutex                    sync.RWMutex
 	timestamp                     *uint
 	timestampMutex                sync.RWMutex
-	nonce                         *trinary.Trytes
-	nonceMutex                    sync.RWMutex
 	signatureMessageFragment      *trinary.Trytes
 	signatureMessageFragmentMutex sync.RWMutex
 
@@ -215,53 +213,6 @@ func (this *ValueTransaction) GetBundleEssence(includeSignatureMessageFragment b
 	return
 }
 
-// getter for the nonce (supports concurrency)
-func (this *ValueTransaction) GetNonce() (result trinary.Trytes) {
-	this.nonceMutex.RLock()
-	if this.nonce == nil {
-		this.nonceMutex.RUnlock()
-		this.nonceMutex.Lock()
-		defer this.nonceMutex.Unlock()
-		if this.nonce == nil {
-			nonce := trinary.MustTritsToTrytes(this.trits[NONCE_OFFSET:NONCE_END])
-
-			this.nonce = &nonce
-		}
-	} else {
-		defer this.nonceMutex.RUnlock()
-	}
-
-	result = *this.nonce
-
-	return
-}
-
-// setter for the nonce (supports concurrency)
-func (this *ValueTransaction) SetNonce(nonce trinary.Trytes) bool {
-	this.nonceMutex.RLock()
-	if this.nonce == nil || *this.nonce != nonce {
-		this.nonceMutex.RUnlock()
-		this.nonceMutex.Lock()
-		defer this.nonceMutex.Unlock()
-		if this.nonce == nil || *this.nonce != nonce {
-			this.nonce = &nonce
-
-			this.BlockHasher()
-			copy(this.trits[NONCE_OFFSET:NONCE_END], trinary.MustTrytesToTrits(nonce)[:NONCE_SIZE])
-			this.UnblockHasher()
-
-			this.SetModified(true)
-			this.ReHash()
-
-			return true
-		}
-	} else {
-		this.nonceMutex.RUnlock()
-	}
-
-	return false
-}
-
 // getter for the signatureMessageFragmetn (supports concurrency)
 func (this *ValueTransaction) GetSignatureMessageFragment() (result trinary.Trytes) {
 	this.signatureMessageFragmentMutex.RLock()