"control_address": txbuilder.DecodeControlAddressAction,
"control_program": txbuilder.DecodeControlProgramAction,
"retire": txbuilder.DecodeRetireAction,
+ "cross_chain_out": txbuilder.DecodeCrossOutAction,
"spend_account": a.wallet.AccountMgr.DecodeSpendAction,
"spend_account_unspent_output": a.wallet.AccountMgr.DecodeSpendUTXOAction,
}
if err != nil {
return err
}
+
redeemContract := address.ScriptAddress()
program := []byte{}
-
switch address.(type) {
case *common.AddressWitnessPubKeyHash:
program, err = vmutil.P2WPKHProgram(redeemContract)
func (a *retireAction) ActionType() string {
return "retire"
}
+
+// DecodeCrossOutAction convert input data to action struct
+func DecodeCrossOutAction(data []byte) (Action, error) {
+ a := new(crossOutAction)
+ err := stdjson.Unmarshal(data, a)
+ return a, err
+}
+
+type crossOutAction struct {
+ bc.AssetAmount
+ Address string `json:"address"`
+}
+
+func (a *crossOutAction) Build(ctx context.Context, b *TemplateBuilder) error {
+ var missing []string
+ if a.Address == "" {
+ missing = append(missing, "address")
+ }
+ if a.AssetId.IsZero() {
+ missing = append(missing, "asset_id")
+ }
+ if a.Amount == 0 {
+ missing = append(missing, "amount")
+ }
+ if len(missing) > 0 {
+ return MissingFieldsError(missing...)
+ }
+
+ address, err := common.DecodeAddress(a.Address, &consensus.MainNetParams)
+ if err != nil {
+ return err
+ }
+
+ redeemContract := address.ScriptAddress()
+ program := []byte{}
+ switch address.(type) {
+ case *common.AddressWitnessPubKeyHash:
+ program, err = vmutil.P2WPKHProgram(redeemContract)
+ case *common.AddressWitnessScriptHash:
+ program, err = vmutil.P2WSHProgram(redeemContract)
+ default:
+ return errors.New("unsupport address type")
+ }
+ if err != nil {
+ return err
+ }
+
+ out := types.NewCrossChainOutput(*a.AssetId, a.Amount, program)
+ return b.AddOutput(out)
+}
+
+func (a *crossOutAction) ActionType() string {
+ return "cross_chain_out"
+}
}
}
-func TestBuild(t *testing.T) {
+func TestBuildIntra(t *testing.T) {
ctx := context.Background()
assetID1 := bc.NewAssetID([32]byte{1})
}
}
+func newCrossOutAction(assetAmt bc.AssetAmount, redeemContract []byte) *crossOutAction {
+ address, err := common.NewAddressWitnessPubKeyHash(redeemContract, &consensus.MainNetParams)
+ if err != nil {
+ panic(err)
+ }
+
+ return &crossOutAction{
+ AssetAmount: assetAmt,
+ Address: address.String(),
+ }
+}
+
+func TestBuildCrossOut(t *testing.T) {
+ ctx := context.Background()
+
+ assetID1 := bc.NewAssetID([32]byte{1})
+ assetID2 := bc.NewAssetID([32]byte{2})
+
+ redeemContract := make([]byte, 20)
+ controlProgram := append([]byte{0x00, byte(len(redeemContract))}, redeemContract...)
+
+ actions := []Action{
+ newCrossOutAction(bc.AssetAmount{AssetId: &assetID2, Amount: 6}, redeemContract),
+ testAction(bc.AssetAmount{AssetId: &assetID1, Amount: 5}),
+ }
+ expiryTime := time.Now().Add(time.Minute)
+ got, err := Build(ctx, nil, actions, expiryTime, 0)
+ if err != nil {
+ testutil.FatalErr(t, err)
+ }
+
+ want := &Template{
+ Transaction: types.NewTx(types.TxData{
+ Version: 1,
+ Inputs: []*types.TxInput{
+ types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), assetID1, 5, 0, nil),
+ },
+ Outputs: []*types.TxOutput{
+ types.NewCrossChainOutput(assetID2, 6, controlProgram),
+ types.NewIntraChainOutput(assetID1, 5, []byte("change")),
+ },
+ }),
+ SigningInstructions: []*SigningInstruction{{
+ WitnessComponents: []witnessComponent{},
+ }},
+ }
+
+ if !testutil.DeepEqual(got.Transaction.TxData, want.Transaction.TxData) {
+ t.Errorf("got tx:\n%s\nwant tx:\n%s", spew.Sdump(got.Transaction.TxData), spew.Sdump(want.Transaction.TxData))
+ }
+
+ if !testutil.DeepEqual(got.SigningInstructions, want.SigningInstructions) {
+ t.Errorf("got signing instructions:\n\t%#v\nwant signing instructions:\n\t%#v", got.SigningInstructions, want.SigningInstructions)
+ }
+}
+
func mustDecodeHex(str string) []byte {
data, err := hex.DecodeString(str)
if err != nil {
// Try to place the data folder in the user's home dir
home := homeDir()
if home == "" {
- return "./.bytom"
+ return "./.vapor"
}
switch runtime.GOOS {
case "darwin":
// In order to be compatible with old data path,
// copy the data from the old path to the new path
- oldPath := filepath.Join(home, "Library", "Bytom")
- newPath := filepath.Join(home, "Library", "Application Support", "Bytom")
+ oldPath := filepath.Join(home, "Library", "Vapor")
+ newPath := filepath.Join(home, "Library", "Application Support", "Vapor")
if !isFolderNotExists(oldPath) && isFolderNotExists(newPath) {
if err := os.Rename(oldPath, newPath); err != nil {
log.Errorf("DefaultDataDir: %v", err)
}
return newPath
case "windows":
- return filepath.Join(home, "AppData", "Roaming", "Bytom")
+ return filepath.Join(home, "AppData", "Roaming", "Vapor")
default:
- return filepath.Join(home, ".bytom")
+ return filepath.Join(home, ".vapor")
}
}