forked from Web3N3/web3-course
Fix buying items from merchants
Signed-off-by: Vladimir Domnich <v.domnich@yadro.com>
This commit is contained in:
parent
9de7e04e0f
commit
fdb6e9fa8b
4 changed files with 35 additions and 3 deletions
|
@ -99,3 +99,7 @@ To create a new player, invoke `newPlayer` function on the player contract and s
|
||||||
neo-go contract invokefunction -r http://localhost:30333 -w ../../wallet.json e7e4910b3a83ce0eff180a3f5462030391fde830 newPlayer string:demo
|
neo-go contract invokefunction -r http://localhost:30333 -w ../../wallet.json e7e4910b3a83ce0eff180a3f5462030391fde830 newPlayer string:demo
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
neo-go contract invokefunction -r http://localhost:30333 -w ../../wallet.json 8d099cb315c03c1f040d8912f1f2a84e569ca50c buyItem string:demo string:Shortbow -- 'NP8wjGz3Wvxe4gUAkTbK2McR95Y4LM2jMW:None'
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: "Merchant"
|
name: "Merchant"
|
||||||
supportedstandards: []
|
supportedstandards: []
|
||||||
events:
|
events:
|
||||||
safemethods: ["getItemName"]
|
safemethods: ["getItemName", "getLotsForSale"]
|
||||||
permissions:
|
permissions:
|
||||||
- methods: ["onNEP17Payment", "transfer"]
|
- methods: ["onNEP17Payment", "transfer"]
|
||||||
|
|
|
@ -2,6 +2,7 @@ package player
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop"
|
"github.com/nspcc-dev/neo-go/pkg/interop"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/interop/iterator"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/native/gas"
|
"github.com/nspcc-dev/neo-go/pkg/interop/native/gas"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/native/std"
|
"github.com/nspcc-dev/neo-go/pkg/interop/native/std"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
||||||
|
@ -47,6 +48,18 @@ func GetItemName(lotID int) string {
|
||||||
return getLot(storage.GetReadOnlyContext(), lotID).itemName
|
return getLot(storage.GetReadOnlyContext(), lotID).itemName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetLotsForSale() []Lot {
|
||||||
|
lots := make([]Lot, 0)
|
||||||
|
|
||||||
|
ctx := storage.GetReadOnlyContext()
|
||||||
|
it := storage.Find(ctx, lotsPrefix, storage.ValuesOnly|storage.DeserializeValues)
|
||||||
|
for iterator.Next(it) {
|
||||||
|
lot := iterator.Value(it).(Lot)
|
||||||
|
lots = append(lots, lot)
|
||||||
|
}
|
||||||
|
return lots
|
||||||
|
}
|
||||||
|
|
||||||
func Sell(itemName string, price int) {
|
func Sell(itemName string, price int) {
|
||||||
ctx := storage.GetContext()
|
ctx := storage.GetContext()
|
||||||
playerHash := storage.Get(ctx, playerHashKey).(interop.Hash160)
|
playerHash := storage.Get(ctx, playerHashKey).(interop.Hash160)
|
||||||
|
@ -63,7 +76,7 @@ func Sell(itemName string, price int) {
|
||||||
gasAmount := price * gasDecimals
|
gasAmount := price * gasDecimals
|
||||||
success := gas.Transfer(runtime.GetExecutingScriptHash(), runtime.GetScriptContainer().Sender, gasAmount, nil)
|
success := gas.Transfer(runtime.GetExecutingScriptHash(), runtime.GetScriptContainer().Sender, gasAmount, nil)
|
||||||
if !success {
|
if !success {
|
||||||
panic("failed to transfer gas")
|
panic("failed to transfer gas to seller")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,11 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/native/std"
|
"github.com/nspcc-dev/neo-go/pkg/interop/native/std"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
"github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/interop/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const gasDecimals = 1_0000_0000
|
||||||
|
|
||||||
var itemPrices = map[string]int{
|
var itemPrices = map[string]int{
|
||||||
"Sword": 100,
|
"Sword": 100,
|
||||||
"Shortbow": 50,
|
"Shortbow": 50,
|
||||||
|
@ -94,7 +97,11 @@ func BuyItemForGas(playerName string, lotID int, itemPrice int, merchantHash int
|
||||||
|
|
||||||
itemName := contract.Call(merchantHash, "getItemName", contract.ReadOnly, lotID).(string)
|
itemName := contract.Call(merchantHash, "getItemName", contract.ReadOnly, lotID).(string)
|
||||||
|
|
||||||
gas.Transfer(runtime.GetScriptContainer().Sender, merchantHash, itemPrice, lotID)
|
gasPrice := itemPrice * gasDecimals
|
||||||
|
success := gas.Transfer(runtime.GetScriptContainer().Sender, merchantHash, gasPrice, lotID)
|
||||||
|
if !success {
|
||||||
|
panic("failed to transfer gas to merchant")
|
||||||
|
}
|
||||||
|
|
||||||
addItemToInventory(player, itemName)
|
addItemToInventory(player, itemName)
|
||||||
savePlayer(ctx, playerName, player)
|
savePlayer(ctx, playerName, player)
|
||||||
|
@ -112,7 +119,15 @@ func SellItemForGas(playerName string, itemName string, itemPrice int, merchantH
|
||||||
}
|
}
|
||||||
removeItemFromInventory(player, itemName)
|
removeItemFromInventory(player, itemName)
|
||||||
|
|
||||||
|
balanceBefore := gas.BalanceOf(runtime.GetScriptContainer().Sender)
|
||||||
contract.Call(merchantHash, "sell", contract.All, itemName, itemPrice)
|
contract.Call(merchantHash, "sell", contract.All, itemName, itemPrice)
|
||||||
|
balanceAfter := gas.BalanceOf(runtime.GetScriptContainer().Sender)
|
||||||
|
|
||||||
|
gasProfit := (balanceAfter - balanceBefore)
|
||||||
|
if gasProfit < itemPrice*gasDecimals {
|
||||||
|
runtime.Log("merchant payment does not cover item price: " + std.Itoa10(gasProfit) + " < " + std.Itoa10(itemPrice*gasDecimals))
|
||||||
|
util.Abort()
|
||||||
|
}
|
||||||
|
|
||||||
savePlayer(ctx, playerName, player)
|
savePlayer(ctx, playerName, player)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue