PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, July 28, 2022

[FIXED] Why does calling sp.address() with a dynamic value inside an entrypoint fail?

 July 28, 2022     blockchain, smartcontracts     No comments   

Issue

is there some way to call sp.address inside an entrypoint and pass in a dynamic String? I have created an example contract showing the failing state:

import smartpy as sp

class DynamicAddressTestContract(sp.Contract):
    def __init__(self, **kargs):
        self.init(**kargs)

    @sp.entry_point
    def test(self, params):
        sp.set_type(params.address, sp.TString)
        addr = sp.address(params.address)
        sp.verify(addr == sp.sender, "INVALID_ADDRESS")
    
@sp.add_test(name = "Dynamic Address")
def test():
    scenario = sp.test_scenario()
    scenario.h1("Unpacked")
    c1 = DynamicAddressTestContract()
    scenario += c1
    alice = sp.test_account("alice")
    
    c1.test(address='tz1h4EsGunH2Ue1T2uNs8mfKZ8XZoQji3HcK').run(sender=alice)

I get the error

Error: Cannot convert expression to bool. Conditionals are forbidden on
contract expressions. Please use ~ or sp.if instead of not or if.

 SmartPy code line 18, in test (line 18)
   scenario += c1
 SmartPy code line 10, in test (line 10)
   addr = sp.address(params.address)

Is there a way to fix this or perhaps another way to achieve this objective?

Smartpy Contract


Solution

That is not possible, sp.address(x) expects x to be a python string.

params.address is a michelson value of type string and michelson does not have any instruction to explicitly cast a string to an address. But you could probably do some "black magic" with sp.pack, sp.slice and sp.unpack to extract the address from a string.

The proper way to do it is to change params.address to be of type address and to remove sp.address(...).

Example

import smartpy as sp

class DynamicAddressTestContract(sp.Contract):
    def __init__(self, **kargs):
        self.init(**kargs)

    @sp.entry_point
    def test(self, params):
        sp.set_type(params.address, sp.TAddress)
        sp.verify(params.address == sp.sender, "INVALID_ADDRESS")
    
@sp.add_test(name = "Dynamic Address")
def test():
    scenario = sp.test_scenario()
    scenario.h1("Unpacked")
    c1 = DynamicAddressTestContract()
    scenario += c1
    alice = sp.test_account("alice")
    
    c1.test(address=sp.address('tz1h4EsGunH2Ue1T2uNs8mfKZ8XZoQji3HcK')).run(sender=alice)

When youre looking for any way to compare a string version of an address with an actual address, via any intermediary type then as far as i can see the closest is to go from raw address > pack+slice to bytes -> encode to base256 > encode to base58 > pack+slice > comparable string but thats too much trouble (byte manipulation is not great in Michelson). Also, you do not really need it.



Answered By - Figario
Answer Checked By - Marilyn (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing