func (h *Helper) ApplyStateDelta(id interface{}, delta *statemgmt.StateDelta) error {
	ledger, err := ledger.GetLedger()
	if err != nil {
		return fmt.Errorf("Failed to get the ledger :%v", err)
	}
	return ledger.ApplyStateDelta(id, delta)
}
ApplyStateDelta applies a state delta to the current state
The result of this function can be retrieved using GetCurrentStateDelta
To commit the result, call CommitStateDelta, or to roll it back
call RollbackStateDelta
package helper
import (
	"fmt"
	"github.com/spf13/viper"
	"golang.org/x/net/context"
	"github.com/openblockchain/obc-peer/openchain/chaincode"
	"github.com/openblockchain/obc-peer/openchain/consensus"
	crypto "github.com/openblockchain/obc-peer/openchain/crypto"
	"github.com/openblockchain/obc-peer/openchain/ledger"
	"github.com/openblockchain/obc-peer/openchain/ledger/statemgmt"
	"github.com/openblockchain/obc-peer/openchain/peer"
	pb "github.com/openblockchain/obc-peer/protos"
)
type Helper struct {
	coordinator peer.MessageHandlerCoordinator
	secOn       bool
	secHelper   crypto.Peer
	curBatch    []*pb.Transaction  
}
func NewHelper(mhc peer.MessageHandlerCoordinator) consensus.Stack {
	return &Helper{coordinator: mhc,
		secOn:     viper.GetBool("security.enabled"),
		secHelper: mhc.GetSecHelper()}
}
func (h *Helper) GetNetworkInfo() (self *pb.PeerEndpoint, network []*pb.PeerEndpoint, err error) {
	ep, err := h.coordinator.GetPeerEndpoint()
	if err != nil {
		return self, network, fmt.Errorf("Couldn't retrieve own endpoint: %v", err)
	}
	self = ep
	peersMsg, err := h.coordinator.GetPeers()
	if err != nil {
		return self, network, fmt.Errorf("Couldn't retrieve list of peers: %v", err)
	}
	peers := peersMsg.GetPeers()
	for _, endpoint := range peers {
		if endpoint.Type == pb.PeerEndpoint_VALIDATOR {
			network = append(network, endpoint)
		}
	}
	network = append(network, self)
	return
}
func (h *Helper) GetNetworkHandles() (self *pb.PeerID, network []*pb.PeerID, err error) {
	selfEP, networkEP, err := h.GetNetworkInfo()
	if err != nil {
		return self, network, fmt.Errorf("Couldn't retrieve validating network's endpoints: %v", err)
	}
	self = selfEP.ID
	for _, endpoint := range networkEP {
		network = append(network, endpoint.ID)
	}
	network = append(network, self)
	return
}
func (h *Helper) Broadcast(msg *pb.OpenchainMessage, peerType pb.PeerEndpoint_Type) error {
	errors := h.coordinator.Broadcast(msg, peerType)
	if len(errors) > 0 {
		return fmt.Errorf("Couldn't broadcast successfully")
	}
	return nil
}
func (h *Helper) Unicast(msg *pb.OpenchainMessage, receiverHandle *pb.PeerID) error {
	return h.coordinator.Unicast(msg, receiverHandle)
}
func (h *Helper) Sign(msg []byte) ([]byte, error) {
	if h.secOn {
		return h.secHelper.Sign(msg)
	}
	logger.Debug("Security is disabled")
	return msg, nil
}
func (h *Helper) Verify(replicaID *pb.PeerID, signature []byte, message []byte) error {
	if !h.secOn {
		logger.Debug("Security is disabled")
		return nil
	}
	logger.Debug("Verify message from: %v", replicaID.Name)
	_, network, err := h.GetNetworkInfo()
	if err != nil {
		return fmt.Errorf("Couldn't retrieve validating network's endpoints: %v", err)
	}
	for _, endpoint := range network {
		logger.Debug("Endpoint name: %v", endpoint.ID.Name)
		if *replicaID == *endpoint.ID {
			cryptoID := endpoint.PkiID
			return h.secHelper.Verify(cryptoID, signature, message)
		}
	}
	return fmt.Errorf("Could not verify message from %s (unknown peer)", replicaID.Name)
}
func (h *Helper) BeginTxBatch(id interface{}) error {
	ledger, err := ledger.GetLedger()
	if err != nil {
		return fmt.Errorf("Failed to get the ledger: %v", err)
	}
	if err := ledger.BeginTxBatch(id); err != nil {
		return fmt.Errorf("Failed to begin transaction with the ledger: %v", err)
	}
	h.curBatch = nil  
	return nil
}
func (h *Helper) ExecTxs(id interface{}, txs []*pb.Transaction) ([]byte, error) {
	res, _ := chaincode.ExecuteTransactions(context.Background(), chaincode.DefaultChain, txs)
	h.curBatch = append(h.curBatch, txs...)  
	return res, nil
}
func (h *Helper) CommitTxBatch(id interface{}, metadata []byte) (*pb.Block, error) {
	ledger, err := ledger.GetLedger()
	if err != nil {
		return nil, fmt.Errorf("Failed to get the ledger: %v", err)
	}
	if err := ledger.CommitTxBatch(id, h.curBatch, nil, metadata); err != nil {
		return nil, fmt.Errorf("Failed to commit transaction to the ledger: %v", err)
	}
	size := ledger.GetBlockchainSize()
	h.curBatch = nil  
	block, err := ledger.GetBlockByNumber(size - 1)
	if err != nil {
		return nil, fmt.Errorf("Failed to get the block at the head of the chain: %v", err)
	}
	return block, nil
}
func (h *Helper) RollbackTxBatch(id interface{}) error {
	ledger, err := ledger.GetLedger()
	if err != nil {
		return fmt.Errorf("Failed to get the ledger: %v", err)
	}
	if err := ledger.RollbackTxBatch(id); err != nil {
		return fmt.Errorf("Failed to rollback transaction with the ledger: %v", err)
	}
	h.curBatch = nil  
	return nil
}
func (h *Helper) PreviewCommitTxBatch(id interface{}, metadata []byte) (*pb.Block, error) {
	ledger, err := ledger.GetLedger()
	if err != nil {
		return nil, fmt.Errorf("Failed to get the ledger: %v", err)
	}
	block, err := ledger.GetTXBatchPreviewBlock(id, h.curBatch, metadata)
	if err != nil {
		return nil, fmt.Errorf("Failed to commit transaction to the ledger: %v", err)
	}
	return block, err
}
func (h *Helper) GetBlock(blockNumber uint64) (block *pb.Block, err error) {
	ledger, err := ledger.GetLedger()
	if err != nil {
		return nil, fmt.Errorf("Failed to get the ledger :%v", err)
	}
	return ledger.GetBlockByNumber(blockNumber)
}
func (h *Helper) GetCurrentStateHash() (stateHash []byte, err error) {
	ledger, err := ledger.GetLedger()
	if err != nil {
		return nil, fmt.Errorf("Failed to get the ledger :%v", err)
	}
	return ledger.GetTempStateHash()
}
func (h *Helper) GetBlockchainSize() (uint64, error) {
	ledger, err := ledger.GetLedger()
	if err != nil {
		return 0, fmt.Errorf("Failed to get the ledger :%v", err)
	}
	return ledger.GetBlockchainSize(), nil
}
func (h *Helper) HashBlock(block *pb.Block) ([]byte, error) {
	return block.GetHash()
}
func (h *Helper) PutBlock(blockNumber uint64, block *pb.Block) error {
	ledger, err := ledger.GetLedger()
	if err != nil {
		return fmt.Errorf("Failed to get the ledger :%v", err)
	}
	return ledger.PutRawBlock(block, blockNumber)
}