Skip to content

qlc_settlement

Goren G edited this page Feb 13, 2020 · 4 revisions

Settlement

  • update data structure
  • add more query interface

update @ 2020/02/13

Backgroud

In order to simplify the settlement smart contract, we plan to implement a settlement smart contract template to generate different settlement smart contracts without writing any code. As settlement portal(front end), I am able to generate smart contract by the contract tempalte RPC interfaces.

The contract template provides interfaces for processing CDR data. By the RPC interfaces, we can save CDR data to block chain. As CDR parser, i am able to store CDR which collected from PCCWG or CSL to blockchain.

Finally, the contract template also provides interfaces for generating reports. As settlement portal(front end), I am able to query records by smart contract RPC interfaces to generate reports.

notic:

  • create/sign settlement contract processes are similar to NEO wrapper
  • RPC interface prefix is settlement, GetCreateContractBlock will be register as settlement_getCreateContractBlock
  • currently there is no SLA rules, will define them when SLA rules are availabe
  • perhaps CDR data structure will be changed when CDR API ready
  • perhaps generate reports interface will be changed in the future

Create/Sign settlement contract

sequence digram

settlement_contract

Interfaces

Data structure

type Contractor struct {
	Address types.Address `json:"address"`
	Name    string        `json:"name"`
}

type ContractService struct {
	ServiceId   string  `json:"serviceId" validate:"nonzero"`
	Mcc         uint64  `json:"mcc"`
	Mnc         uint64  `json:"mnc"`
	TotalAmount uint64  `json:"totalAmount" validate:"min=1"`
	UnitPrice   float64 `son:"unitPrice" validate:"nonzero"`
	Currency    string  `json:"currency" validate:"nonzero"`
}

type CreateContractParam struct {
	PartyA    Contractor        `json:"partyA"`
	PartyB    Contractor        `json:"partyB"`
	Previous  types.Hash        `json:"previous"`
	Services  []ContractService `json:"services"`
	SignDate  int64             `json:"signDate"`
	StartDate int64             `json:"startDate"`
	EndData   int64             `json:"endData"`
}
type SignContractParam struct {
	ContractAddress types.Address `json:"contractAddress"`
	ConfirmDate     int64         `json:"confirmDate"`
	Address         types.Address
}
// cabi.ContractParam
type ContractParam struct {
	CreateContractParam
	ConfirmDate int64            `msg:"t2" json:"confirmDate"`
	SignatureB  *types.Signature `msg:"sb,extension" json:"signatureB,omitempty"`
}

type SignContractParam struct {
	ContractAddress types.Address `json:"contractAddress"`
	ConfirmDate     int64         `json:"confirmDate"`
	Address         types.Address 
}
// SettlementContract settlement contract for RPC
type SettlementContract struct {
	CreateContractParam
	PreStops    []string       `json:"preStops"`
	NextStops   []string       `json:"nextStops"`
	ConfirmDate int64          `json:"confirmDate"`
	Status      ContractStatus `json:"status"`
	Address     types.Address  `json:"address"`
}
type StopParam struct {
	ContractAddress types.Address `json:"contractAddress"`
	StopName        string        `json:"stopName" validate:"nonzero"`
	Address         types.Address `json:"address"` //user address
}

type UpdateStopParam struct {
	ContractAddress types.Address `json:"contractAddress"`
	StopName        string        `json:"stopName" validate:"nonzero"`
	New             string        `json:"newName" validate:"nonzero"`
	Address         types.Address `json:"address"`
}
type SettlementCDR struct {
	CDRParam
	From types.Address `json:"from"`
}

type CDRStatus struct {
	Params []SettlementCDR  `json:"params"`
	Status SettlementStatus `json:"status"`
}

RPC

  • for create and sign smart contract

    // GetCreateContractBlock
    // generate ContractSend block to call smart contract for generating settlement contract as PartyA
    // @param param smart contract params
    // @return state block to be processed
    func (s *SettlementAPI) GetCreateContractBlock(param *cabi.CreateContractParam) (*types.StateBlock, error) {}
    
    // GetSignContractBlock
    // generate ContractSend block to call smart contract for signing settlement contract as PartyB
    // smart contract address = hash(*abi.CreateContractParam)
    // param.SignatureB = sign(smart contract address + param.ConfirmDate)
    // @param param sign settlement contract param created by PartyA
    // @return state block(without signature) to be processed
    func (s *SettlementAPI) GetSignContractBlock(param *SignContractParam) (*types.StateBlock, error) {}
    
    // GetContractRewardsBlock generate create contract rewords block by contract send block hash
    // pair of `GetCreateContractBlock`
    // @param send contract send block hash
    // @return contract rewards block
    func (s *SettlementAPI) GetContractRewardsBlock(send *types.Hash) (*types.StateBlock, error) {}
    
    // GetSignRewardsBlock generate create contract rewords block by contract send block hash
    // pair of `GetSignContractBlock`
    // @param send contract send block hash
    // @return contract rewards block
    func (s *SettlementAPI) GetSignRewardsBlock(send *types.Hash) (*types.StateBlock, error) {}
  • for add/remove/update previous and next stops

    // previous stop,only can be changed by PartyB
    func (s *SettlementAPI) GetAddPreStopBlock(param *StopParam) (*types.StateBlock, error){}
    func (s *SettlementAPI) GetAddPreStopRewardsBlock(send *types.Hash) (*types.StateBlock, error){}
    func (s *SettlementAPI) GetRemovePreStopBlock(param *StopParam) (*types.StateBlock, error) {}
    func (s *SettlementAPI) GetRemovePreStopRewardsBlock(send *types.Hash) (*types.StateBlock, error) {}
    func (s *SettlementAPI) GetUpdatePreStopBlock(param *UpdateStopParam) (*types.StateBlock, error) {}
    func (s *SettlementAPI) GetUpdatePreStopRewardsBlock(send *types.Hash) (*types.StateBlock, error) {}
    
    // next stop,only can be changed by PartyA
    func (s *SettlementAPI) GetAddNextStopBlock(param *StopParam) (*types.StateBlock, error){}
    func (s *SettlementAPI) GetAddNextStopRewardsBlock(send *types.Hash) (*types.StateBlock, error){}
    func (s *SettlementAPI) GetRemoveNextStopBlock(param *StopParam) (*types.StateBlock, error) {}
    func (s *SettlementAPI) GetRemoveNextStopRewardsBlock(send *types.Hash) (*types.StateBlock, error) {}
    func (s *SettlementAPI) GetUpdateNextStopBlock(param *UpdateStopParam) (*types.StateBlock, error) {}
    func (s *SettlementAPI) GetUpdateNextStopRewardsBlock(send *types.Hash) (*types.StateBlock, error) {}
  • for query contract data

    // GetContractsByAddress query all related settlement contracts info by address
    // @param addr user qlcchain address
    // @param count max settlement contract records size
    // @param offset offset of all settlement contract records(optional)
    // @return all settlement contract
    func (s *SettlementAPI) GetContractsByAddress(addr *types.Address, count int, offset *int) ([]*SettlementContract, error) {}
    
    // GetContractsAsPartyA query all settlement contracts as Party A info by address
    // @param addr user qlcchain address
    // @param count max settlement contract records size
    // @param offset offset of all settlement contract records(optional)
    // @return all settlement contract as PartyA
    func (s *SettlementAPI) GetContractsAsPartyA(addr *types.Address, count int, offset *int) ([]*SettlementContract, error) {} 
    
    // GetContractsAsPartyA query all settlement contracts as Party B info by address
    // @param addr user qlcchain address
    // @param count max settlement contract records size
    // @param offset offset of all settlement contract records(optional)
    // @return all settlement contract as PartyB
    func (s *SettlementAPI) GetContractsAsPartyB(addr *types.Address, count int, offset *int) ([]*SettlementContract, error) {} 
    
    // GetAllContracts query all settlement contracts
    // @param count max settlement contract records size
    // @param offset offset of all settlement contract records(optional)
    // @return all settlement contracts
    func (s *SettlementAPI) GetAllContracts(count int, offset *int) ([]*SettlementContract, error) {}
  • for query settlement result

    // GetAllCDRStatus get all cdr status of the specific settlement smart contract
    // @param addr settlement smart contract
    // @param count max settlement contract records size
    // @param offset offset of all settlement contract records(optional)
    func (s *SettlementAPI) GetAllCDRStatus(addr *types.Address, count int, offset *int) ([]*cabi.CDRStatus, error){}
    
    // GetCDRStatus get CDRstatus by settlement smart contract address and CDR hash
    // @param addr settlement smart contract address
    // @param hash CDR data hash
    func (s *SettlementAPI) GetCDRStatus(addr *types.Address, hash types.Hash) (*cabi.CDRStatus, error) {}
  • util

    // ToAddress convert CreateContractParam to smart contract address
    // hash(cabi.CreateContractParam)
    func (s *SettlementAPI) ToAddress(param *cabi.CreateContractParam) (types.Address, error) {}

Process CDR

sequence diagram

settlement_cdr

Interfaces

Data structure

type CDRParam struct {
	ContractAddress types.Address `json:"contractAddress"`
	Index           uint64        `json:"index" validate:"min=1"`
	SmsDt           int64         `json:"smsDt" validate:"min=1"`
	Sender          string        `json:"sender" validate:"nonzero"`
	Destination     string        `json:"destination" validate:"nonzero"`
	SendingStatus   SendingStatus `json:"sendingStatus" `
	DlrStatus       DLRStatus     `json:"dlrStatus"`
	PreStop         string        `json:"preStop" `
	NextStop        string        `json:"nextStop" `
}

RPC

// GetProcessCDRBlock save CDR data for the settlement
// @param addr settlement smart contract address
// @param params CDR params to be processed
// @return contract send block to be processed
func (s *SettlementAPI) GetProcessCDRBlock(addr *types.Address, params []*CDRParam) ([]*types.StateBlock, error) { }

//
func (s *SettlementAPI) GetProcessCDRRewardsBlock(send *types.Hash) (*types.StateBlock, error) {}

Generate reports data structure and interface

// TODO: report data te be confirmed
type SettlementRecord struct {
    Address                  types.Address // smart contract address
    Customer                 string
    CustomerSR               string
    Country                  string
    Operator                 string
    ServiceId                string
    MCC                      int
    MNC                      int
    Currency                 string
    UnitPrice                float64
    SumOfBillableSMSCustomer int64
    SumOfTOTPrice            float64
}

// TODO: query condition to be confirmed, maybe more interface?
// GenerateReport Generate reports for specified contracts based on start and end date
// @param addr user qlcchain address
// @param start report start date
// @param end report end data
// @return settlement records for report
func (s *SettlementAPI) GenerateReport(addr *types.Address, start, end time.Time) (*[]SettlementRecord, error) { }