Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A journey from Swift to Solidity

A journey from Swift to Solidity

Kristaps, Crypto Cat at Salto X, shares his story of how he transitioned from iOS to the Web3 world. We discuss how Ethereum blockchains look in the eyes of a mobile developer and explore the similarities and differences between Swift and Solidity programming languages. Guess what? Solidity is much more similar to Swift than Javascript.

Kristaps Grinbergs

August 24, 2022
Tweet

More Decks by Kristaps Grinbergs

Other Decks in Programming

Transcript

  1. – swift.org “Swift is designed to make writing and maintaining

    correct programs easier for the developer.”
  2. Deterministic adjective Believing that everything that happens must happen as

    it does and could not have happened any other way.
  3. Multi-party agreement Agreement between 🇺🇦, 🇷🇺 and 🇹🇷 (supported by

    🇺🇳). 🇷🇺 will not target ports while shipments are in transit. 🇺🇦 vessels will guide cargo ships through waters that have been mined. 🇹🇷 - supported by the 🇺🇳 - will inspect ships, to allay 🇷🇺 fears of weapons smuggling.
  4. Logistics • 🇺🇦 registers shipment • The ship goes from

    🇺🇦 to 🇹🇷 through mines • 🇹🇷 checks ship if nothing is being smuggled • The ship leaves 🇹🇷 • Arrives in the destination country, 🇺🇳 approves
  5. Agreement address private ukraine; address private russia; address private turkey;

    address private un; bool private ukraineSigned; bool private russiaSigned; bool private turkeySigned; bool private unSigned; event SignedByUkraine(); event SignedByRussia(); event SignedByTurkey(); event SignedByUN(); event AgreementSigned(); Wallet addresses Signed status Sign event
  6. Initial setup constructor(address _ukraine, address _russia, address _turkey, address _un)

    { ukraine = _ukraine; russia = _russia; turkey = _turkey; un = _un; }
  7. Agreement function sign() external { console.log("Signer address", msg.sender); require(msg.sender ==

    ukraine || msg.sender == russia || msg.sender == turkey || msg.sender == un, "Unknown signer"); if (msg.sender == ukraine) { ukraineSigned = true; emit SignedByUkraine(); } if (msg.sender == russia) { russiaSigned = true; emit SignedByRussia(); } if (msg.sender == turkey) { turkeySigned = true; emit SignedByTurkey(); } if (msg.sender == un) { unSigned = true; emit SignedByUN(); } if (ukraineSigned && russiaSigned && turkeySigned && unSigned) { emit AgreementSigned(); } } Emit event Check wallet address Agreement signed
  8. Agreement struct ContentView: View { @StateObject var appData = AppData()

    private var agreementSigned: Bool { appData.ukraineSigned && appData.russiaSigned && appData.turkeySigned && appData.unSigned } var body: some View { NavigationStack { VStack(spacing: 30) { Spacer() CountryButtonView(country: .ukraine) { appData.ukraineSigned = true }.disabled(appData.ukraineSigned) CountryButtonView(country: .russia) { appData.russiaSigned = true }.disabled(appData.russiaSigned) CountryButtonView(country: .turkey) { appData.turkeySigned = true }.disabled(appData.turkeySigned) CountryButtonView(country: .un) { appData.unSigned = true }.disabled(appData.unSigned) Spacer() NavigationLink { ShipmentView() } label: { Text("Next") .font(.title2) } .disabled(!agreementSigned) } } .environmentObject(appData) } }
  9. Agreement signed @StateObject var appData = AppData() private var agreementSigned:

    Bool { appData.ukraineSigned && appData.russiaSigned && appData.turkeySigned && appData.unSigned } NavigationLink { ShipmentView() } label: { Text("Next") .font(.title2) } .disabled(!agreementSigned)
  10. AppData class AppData: ObservableObject { @Published var ukraineSigned: Bool =

    false @Published var russiaSigned: Bool = false @Published var turkeySigned: Bool = false @Published var unSigned: Bool = false
  11. Modi fi er modifier agreementSigned() { require(ukraineSigned, "Ukraine not signed");

    require(russiaSigned, "Russia not signed"); require(turkeySigned, "Turkey not signed"); require(unSigned, "United Nations not signed"); _; }
  12. ShipmentStatus enum ShipmentStatus { InUkraine, // Registered in Ukraine LeftUkraine,

    // Navigating in Black Sea ArrivedInTurkey, // Arrived in Turkey LeftTurkey, // Left Turkey ArrivedInDestinationCountry // Arrived to the destination country } enum ShipmentStatus { case inUkraine // Registered in Ukraine case leftUkraine // Navigating in Black Sea case arrivedInTurkey // Arrived in Turkey case leftTurkey // Left Turkey case arrivedInDestinationCountry // Arrived to the destination country }
  13. Shipment struct Shipment { string destination; ShipmentStatus status; } struct

    Shipment: Identifiable { var id: Int var destination: String var status: ShipmentStatus }
  14. Create shipment - Solidity function createShipment(string memory _destination) external agreementSigned

    { require(msg.sender == ukraine, "Caller is not Ukraine"); currentShipmentId++; shipments[currentShipmentId] = Shipment(_destination, ShipmentStatus.InUkraine); console.log("Shipment created", currentShipmentId); emit ShipmentCreated(currentShipmentId); }
  15. Create shipment - iOS struct AddShipmentView: View { @Environment(\.presentationMode) var

    presentationMode @EnvironmentObject var appData: AppData @State private var destination: String = "" var body: some View { NavigationStack { Form { Section { TextField("Destination", text: $destination) } Section { Button("Save", action: saveShipment) } } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Cancel", action: closeModal) } } } } }
  16. Create shipment - iOS func saveShipment() { let shipment =

    Shipment( id: Int(Date().timeIntervalSince1970), destination: destination, status: .inUkraine ) Task { @MainActor in appData.shipments.append(shipment) } closeModal() }
  17. Left Ukraine - Solidity function leftUkraine(uint256 shipmentId) external agreementSigned {

    require(msg.sender == ukraine, "Caller is not Ukraine"); shipments[shipmentId].status = ShipmentStatus.LeftUkraine; console.log("Shipment left Ukraine", shipmentId); emit ShipmentLeftUkraine(shipmentId); }
  18. Left Ukraine - iOS struct ChangeShipmentStatusView: View { @EnvironmentObject var

    appData: AppData @Environment(\.presentationMode) var presentationMode @State private var showSelectCountryAlert = false var shipment: Shipment private var nextStatus: ShipmentStatus { switch shipment.status { case .inUkraine: return .leftUkraine case .leftUkraine: return .arrivedInTurkey case .arrivedInTurkey: return .leftTurkey case .leftTurkey: return .arrivedInDestinationCountry case .arrivedInDestinationCountry: return .arrivedInDestinationCountry } }
  19. Left Ukraine - iOS var body: some View { NavigationStack

    { VStack { Button { changeStatusFor(to: nextStatus) } label: { Text(nextStatus.description) .font(.title3) .padding(10) } .buttonStyle(.borderedProminent) } } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Cancel", action: closeModal) } } .alert(isPresented: $showSelectCountryAlert) { Alert( title: Text("Please select correct country"), message: Text("To continue please select correct country") ) } } }
  20. Arrives in Turkey - Solidity function arrivesInTurkey(uint256 shipmentId) external agreementSigned

    { require(msg.sender == turkey, "Caller is not Turkey"); shipments[shipmentId].status = ShipmentStatus.ArrivedInTurkey; console.log("Shipment arrived in Turkey", shipmentId); emit ShipmentArrivedInTurkey(shipmentId); }
  21. Arrives in Turkey - Swift func changeStatusFor(to status: ShipmentStatus) {

    var shipment = shipment switch status { case .inUkraine: return /// case .arrivedInTurkey: guard checkCountryIfSelectedIs(.turkey) else { showSelectCountryAlert = true return } shipment.status = .arrivedInTurkey
  22. Arrives in Turkey - Swift .sheet(isPresented: $showCountrySwitch) { VStack {

    CountryButtonView(country: .ukraine, font: .body) { appData.activeCountry = .ukraine closeSheet() } CountryButtonView(country: .russia, font: .body) { appData.activeCountry = .russia closeSheet() } CountryButtonView(country: .turkey, font: .body) { appData.activeCountry = .turkey closeSheet() } CountryButtonView(country: .un, font: .body) { appData.activeCountry = .un closeSheet() } } .presentationDetents([.medium]) .padding(.vertical, 40) }
  23. Arrives in Turkey - Swift case .arrivedInTurkey: guard checkCountryIfSelectedIs(.turkey) else

    { showSelectCountryAlert = true return } shipment.status = .arrivedInTurkey
  24. Examined - Solidity function arrivesInTurkey(uint256 shipmentId) external agreementSigned { require(msg.sender

    == turkey, "Caller is not Turkey"); shipments[shipmentId].status = ShipmentStatus.ArrivedInTurkey; console.log("Shipment arrived in Turkey", shipmentId); emit ShipmentArrivedInTurkey(shipmentId); }
  25. Arrived in destination - Solidity function arrivedInDestination(uint256 shipmentId) external agreementSigned

    { require(msg.sender == un, "Caller is not United Nations"); shipments[shipmentId].status = ShipmentStatus.ArrivedInDestinationCountry; console.log("Shipment", shipmentId, "arrived in", shipments[shipmentId].destination); emit ShipmentArrivedInDestination(shipmentId, shipments[shipmentId].destination); }
  26. Arrived in destination - Swift case .arrivedInDestinationCountry: guard checkCountryIfSelectedIs(.un) else

    { showSelectCountryAlert = true return } shipment.status = .arrivedInDestinationCountry